ioStreamの取扱について
はじめに
Pythonでファイルの入出力処理を行う場合を考えます。私の例だと、ファイルの形式を変換して保存する処理を実装しました。この場合、ファイルの書き出しについて入門サイトでは新規ファイルをローカルに書き出して、データを追記する手順が紹介されます。しかしながら、ファイルとして保存する手順を踏まないでメモリ上で変換を完結させたいケースがあります(私の例では、ウェブアプリとして変換ツールを作成したので、どこにもファイルを保存しないで処理したかった)。
ioStreamの導入
標準ライブラリのひとつです。Python2と3でimport対象が異なります。
- Python2の場合
#StringIO from StringIO import StringIO #stringio = StringIO() #BytesIO import io #bytesio = io.BytesIO()
- Python3の場合
#StringIO,BytesIO共通 import io #stringio = io.StringIO() #bytesio = io.BytesIO()
ioStreamの使い方
ioStreamのイメージとしては、保存先がメモリ上になっているファイルです。したがって、処理の最中の一時的な保存に向いています。また、その特性上処理が終わると消えてしまいます(メモリ管理とかはよくわかんないです)。
- 実装例
#メモリ上のファイルとして定義 f = StringIO() #以下の行でCSVファイルをメモリ上に書き出し #よくある解説では、書き出し先のパスを指定したりするが、今回はStringIO()を指定 writer = csv.writer(f, quotechar='"', quoting=csv.QUOTE_ALL, lineterminator="\n") #以下なんやかんやCSVファイルにデータを追記 names = [] for field in in_db.header.fields: names.append(field.name) writer.writerow(names) for rec in in_db: writer.writerow(rec.fieldData) #StringIO()の中身(CSVファイル)を取得する場合、必ずgetvalue() return f.getvalue()
StringIO vs BytesIO
一応、データの内容が文字列の場合StringIOを用いる、とされています。また先程紹介したとおり、Python2とPython3でインポートするモジュールが異なります。そんなわけで、互換性を考えるならBytesIOを使っておけば、2でも3でも同様に書けますね(どちらもio.BytesIO()であるため)。文字列データをBytesIOに入れたければエンコードしてバイト列に変換してから突っ込めばよいです。
まとめ
データの入出力はよくある処理だと思いますが、その処理ごとにいちいちデータを保存していると色々と面倒くさいはずですので、ioStreamを活用してシンプルなアプリケーションをつくりましょう。