GAEは実行時にファイルシステムに書き込むことが出来ないけど、コード中でファイル経由操作をしたいことが案外あるので、ちょっと調べてみた。
この場合に便利に使えるのがBytesIOと言うヤツ。
ファイルIO処理のターゲットとして使えて、オンメモリでデータを保持して、Bytesデータとして取り扱いも出来る。
PILで画像を処理してGCSにアップロードするときに、PIL画像をいったん置くのに利用してみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import io from PIL import Image from google-cloud import storage bio = io.BytesIO() Image.save(bio, format='JPEG') blob = storage.Blob('filename', bucket) #ファイルオブジェクトとして扱う場合 blob.upload_from_file(bio) #バイトオブジェクトとして扱う場合 blob.upload_from_string(data=bio.getvalue(), content_type='application/octet-stream') |
upload_from_fileはファイルオブジェクトから読み取ってアップするメソッドなので、bioを与えればファイル同様に先頭から読んでいってアップしてくれる。
upload_from_stringは文字列を保存するためのものだけど、Bytes型を通せるのでbioにgetvalueしてBytes型で値をまるごと渡してもいける。
プログラムのコード上、ファイルに保存するライブラリの出力を直接データ加工したければgetvalueで取って、ファイルを読み取って動作するライブラリならオブジェクトをそのまま使えば良い。 ライブラリの中身を知っていればデータを取っていじっても良いけど、ファイル入出力を使うのが普通の場合はBytesIOを通せば従来のコードに余り手を入れずにGAE環境でも使える。 NANDとかの環境で書き込み回数制限を気にしたい組み込みとかでも使うと良さそうだ。
(1189)