pythonで一時ファイルにデータを書き込み、終わったらリネーム

システム間でデータをファイルでやり取りするケースはときどきあります。

作成中のファイルを読み込まれないようにするため、普通は一時ファイルにデータを書き込んでいき、全て書き込んだ後にファイルをコピーするなり、リネームすると思います。

コピーやリネームがアトミックに処理されれば、中途半端なファイルが持っていかれることはありません。

pythonでは一時ファイルを作成するtempfileというモジュールがありますので、これを使って上記のような処理をどう書くか、試しに書いてみたのでメモしておきます。


こんな感じになりました

# coding=utf-8
import os
import tempfile

filename = 'out.txt'
output_dir = os.path.join(os.path.dirname(__file__), 'output_dir')

with tempfile.NamedTemporaryFile(delete=False) as tf:
    # ファイルに書き込む処理
    tf.write('hello')
    temp_file_name = tf.name

print temp_file_name
# /var/folders/fb/drnqpdzd58vgyllnn4p_8tb40000gn/T/tmpaeg3Ve

# リネーム
os.rename(temp_file_name, os.path.join(output_dir, filename))


一時ファイルは何もしないと/var/folders/fb以下にランダムな感じで書き込まれました。
このディレクトリはNamedTemporaryFileにキーワード引数dirを渡すことによって変更することができます。


またファイル名はtmpaeg3Veという名前になりましたが、この「tmp」の部分はキーワード引数prefixを渡すことによって変更できます。


キーワード引数deleteにFalseを渡すことによって、ファイルハンドラをcloseしても一時ファイルは削除されなくなります。
デフォルトはTrueなので何も指定しないと削除されます。


上記のコードの場合delete=Falseを指定しないと、renameの段階で一時ファイルは削除されてますので、No such file or directoryになります。