# 11.6. `tempfile` --- 一時ファイルやディレクトリの作成

ソースコード: Lib/tempfile.py

このモジュールは一時ファイルやディレクトリを作成します。 サポートされている全てのプラットフォームで動作します。 `TemporaryFile`、`NamedTemporaryFile`、`TemporaryDirectory`、 `SpooledTemporaryFile` は自動的に後始末をし、コンテクスト管理者として使うことの出来る高水準のインターフェイスです。 `mkstemp()` と `mkdtemp()` は手動で後始末をしなければならない低水準の関数です。

ユーザが呼び出し可能な全ての関数とコンストラクタは追加の引数を受け取ります。 その引数によって一時ファイルやディレクトリの場所と名前を直接操作することが出来ます。 このモジュールに使用されるファイル名はランダムな文字を含みます。そのためファイルは共有された一時ディレクトリに安全に作成されます。 後方互換性を保つために引数の順序は若干奇妙です。 分かりやすさのためにキーワード引数を使用してください。

このモジュールではユーザが呼び出し可能な以下の項目を定義しています:

`tempfile.``TemporaryFile`(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None)

  一時的な記憶領域として使うことの出来る file-like object を返します。 ファイルは `mkstemp()` と同じルールにより安全に作成されます。 オブジェクトは閉じられる (オブジェクトのガベージコレクションによる暗黙的なものも含みます) とすぐに破壊されます。 Unix では、そのファイルのディレクトリエントリは全く作成されないか、ファイル作成後すぐに削除されます。 これは他のプラットフォームではサポートされません。 よって、この関数で作成された一時ファイルがファイルシステムで可視な名前を持つかどうかをコードで当てにすべきではありません。

  返されたオブジェクトをコンテクスト管理者として使うことが出来ます （使用例 を参照してください）。 コンテクストの完了やファイルオブジェクトの破壊で、一時ファイルはファイルシステムから削除されます。

  作成されたファイルを閉じることなく読み書きできるように、 mode 引数のデフォルトは `'w+b'` です。 保存されるデータに関わらず全てのプラットフォーム上で一貫して動作するようにバイナリモードが使用されます。 buffering、encoding、newline は、 `open()` に対する引数として解釈されます。

  dir、prefix、suffix 引数の意味とデフォルトは `mkstemp()` のものと同じです。

  返されたオブジェクトは、POSIXプラットフォームでは本物のファイルオブジェクトです。 それ以外のプラットフォームでは、`file` 属性が下層の本物のファイルであるファイル様オブジェクトです。

  `os.O_TMPFILE` フラグは、利用可能で動作する場合に用いられます (Linux 固有で、Linux kernel 3.11 以降)。

  バージョン 3.5 で変更: 利用可能であれば `os.O_TMPFILE` フラグが使用されます。

`tempfile.``NamedTemporaryFile`(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True)

  この関数は、ファイルシステム上でファイルが可視の名前を持つことが保証される (Unix においてはディレクトリエントリが unlink されない) 点以外は `TemporaryFile()` と正確に同じことを行います。 その名前は、返されたファイル様オブジェクトの `name` 属性から取得することができます。 名前付き一時ファイルがまだ開かれている間にこの名前を使って再度ファイルを開くことができるかどうかは、プラットフォームによって異なります (Unix 上では可能ですが、 Windows NT 以降ではできません)。 delete が真の場合 (デフォルト)、ファイルは閉じられたら即座に削除されます。 返されたオブジェクトは常にファイル様オブジェクトで、その `file` 属性は元になった本物のファイルオブジェクトです。 このファイルライクオブジェクトは、通常のファイルのように `with` 文の中で使用することができます。

`tempfile.``SpooledTemporaryFile`(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None)

  この関数はファイルサイズが max_size を超えるかファイルの `fileno()` メソッドが呼ばれるまで、データがメモリにスプールされる点以外は `TemporaryFile()` と正確に同じことを行います。 上記条件を満たすと内容はディスクに書き込まれ、操作は `TemporaryFile()` と同様に進みます。

  この関数が返すファイルは、追加で1つのメソッド `rollover()` を持っています。このメソッドが呼ばれると、(サイズに関係なく)メモリからディスクへのロールオーバーが実行されます。

  返されたオブジェクトはファイル様オブジェクトで、その `_file` 属性は (バイナリかテキスト mode が指定されたかどうかに依存して) `io.BytesIO` か `io.StringIO` オブジェクト、あるいは `rollover()` が呼ばれたかどうかに依存して本物のファイルオブジェクトになります。 このファイル様オブジェクトは、通常のファイルオブジェクトと同じように `with` 文中で使用することが出来ます。

  バージョン 3.3 で変更: truncate メソッドが `size` 引数を受け取るようになりました。

`tempfile.``TemporaryDirectory`(suffix=None, prefix=None, dir=None)

  この関数は `mkdtemp()` と同じルールを使用して安全に一時ディレクトリを作成します。 返されたオブジェクトは、コンテクスト管理者として使用することができます (with文とコンテキストマネージャ を参照)。 コンテクストの完了や一時ディレクトリの破壊で新規作成された一時ディレクトリとその中身はファイルシステムから削除されます。

  ディレクトリ名は返されたオブジェクトの `name` 属性から取得することが出来ます。返されたオブジェクトがコンテクスト管理者として使用された場合、1つなら `name` は `with` 文内の `as` のターゲットに割り当てられます。

  `cleanup()` メソッドを呼んでディレクトリを明示的に片付けることができます。

  バージョン 3.2 で追加.

`tempfile.``mkstemp`(suffix=None, prefix=None, dir=None, text=False)

  可能な限り最も安全な手段で一時ファイルを生成します。 プラットフォームが `os.open()` の `os.O_EXCL` フラグを正しく実装している限り、ファイルの作成で競合が起こることはありません。 作成したユーザのユーザ ID からのみファイルを読み書き出来ます。 プラットフォームがファイルが実行可能かどうかを示す許可ビットを使用している場合、ファイルは誰からも実行不可です。 このファイルのファイル記述子は子プロセスに継承されません。

  `TemporaryFile()` と違って、 `mkstemp()` のユーザは用済みになった時に一時ファイルを削除しなければなりません。

  suffix が `None` でない場合、ファイル名はその接尾辞で終わります。 そうでない場合、接尾辞はありません。 `mkstemp()` はファイル名と接尾辞の間にドットを追加しません。 必要であれば suffix の先頭につけてください。

  prefix が `None` でない場合、ファイル名はその接頭辞で始まります。 そうでない場合、デフォルトの接頭辞が使われます。 必要に応じ、デフォルトは `gettempprefix()` または `gettempprefixb()` の返り値です。

  dir が `None` でない場合、ファイルはそのディレクトリ下に作成されます。 `None` の場合、デフォルトのディレクトリが使われます。デフォルトのディレクトリはプラットフォームに依存するリストから選ばれますが、アプリケーションのユーザは TMPDIR、TEMP、または TMP 環境変数を設定することでディレクトリの場所を管理することができます。そのため、生成されるファイル名が、`os.popen()` で外部コマンドにクォーティング無しで渡すことができるなどといった、扱いやすい性質を持つ保証はありません。

  suffix、prefix、dir のいずれかが `None` でない場合、それらは同じ型でなければなりません。 bytes の場合、返された名前は str でなはく bytes です。 他の挙動はデフォルトで返り値を bytes に強制的にしたい場合は `suffix=b''` を渡してください。

  text が指定された場合、ファイルをバイナリモード (デフォルト) かテキストモードで開くかを示します。 プラットフォームによってはこの値を設定しても変化はありません。

  `mkstemp()` は開かれたファイルを扱うための OS レベルのハンドル (`os.open()` が返すものと同じ) とファイルの絶対パス名が順番に並んだタプルを返します。

  バージョン 3.5 で変更: suffix、prefix、dir は bytes の返り値を得るために bytes で渡すことが出来ます。 それ以前は str のみ許されていました。 適切なデフォルト値を使用するよう、suffix と prefix は `None` を受け入れ、デフォルトにするようになりました。

`tempfile.``mkdtemp`(suffix=None, prefix=None, dir=None)

  可能な限り安全な方法で一時ディレクトリを作成します。 ディレクトリの生成で競合は発生しません。 ディレクトリを作成したユーザ ID だけが、このディレクトリに対して内容を読み出したり、書き込んだり、検索したりすることができます。

  `mkdtemp()` のユーザは用済みになった時に一時ディレクトリとその中身を削除しなければなりません。

  prefix, suffix, dir 引数は `mkstemp()` 関数のものと同じです。

  `mkdtemp()` は新たに生成されたディレクトリの絶対パス名を返します。

  バージョン 3.5 で変更: suffix、prefix、dir は bytes の返り値を得るために bytes で渡すことが出来ます。 それ以前は str のみ許されていました。 適切なデフォルト値を使用するよう、suffix と prefix は `None` を受け入れ、デフォルトにするようになりました。

`tempfile.``gettempdir`()

  一時ファイルに用いられるディレクトリの名前を返します。 これはモジュール内の全ての関数の dir 引数のデフォルト値を定義します。

  Python は呼び出したユーザがファイルを作ることの出来るディレクトリを検索するのに標準的なリストを使用します。 そのリストは:

  1. 環境変数 `TMPDIR` で与えられているディレクトリ名。

  2. 環境変数 `TEMP` で与えられているディレクトリ名。

  3. 環境変数 `TMP` で与えられているディレクトリ名。

  4. プラットフォーム依存の場所:

     - Windows ではディレクトリ `C:\TEMP` 、 `C:\TMP` 、 `\TEMP` 、および `\TMP` の順。

     - その他の全てのプラットフォームでは、 `/tmp` 、 `/var/tmp` 、および `/usr/tmp` の順。

  5. 最後の手段として、現在の作業ディレクトリ。

  この検索の結果はキャッシュされます。以下の `tempdir` の記述を参照してください。

`tempfile.``gettempdirb`()

  `gettempdir()` と同じですが返り値は bytesです。

  バージョン 3.5 で追加.

`tempfile.``gettempprefix`()

  一時ファイルを生成する際に使われるファイル名の接頭辞を返します。 これにはディレクトリ部は含まれません。

`tempfile.``gettempprefixb`()

  `gettempprefix()` と同じですが返り値は bytes です。

  バージョン 3.5 で追加.

モジュールはグローバル変数を使用して、 `gettempdir()` が返す、一時ファイルに用いられるディレクトリ名を記憶します。 直接設定して選考過程を上書き出来ますが、推奨されません。 このモジュールの全ての関数はディレクトリを指定する dir 引数を受け取ります。 この方法が推奨されます。

`tempfile.``tempdir`

  `None` 以外の値に設定された場合、このモジュールで定義されている全ての関数の dir 引数のデフォルト値として定義されます。

  `tempdir` が (デフォルトの) `None` の場合、 `gettempprefix()` を除く上記のいずれかの関数を呼び出す際は常に `gettempdir()` で述べられているアルゴリズムによって初期化されます。

## 11.6.1. 使用例

`tempfile` モジュールの典型的な使用法のいくつかの例を挙げます:

    >>> import tempfile

    # create a temporary file and write some data to it
    >>> fp = tempfile.TemporaryFile()
    >>> fp.write(b'Hello world!')
    # read data from file
    >>> fp.seek(0)
    >>> fp.read()
    b'Hello world!'
    # close the file, it will be removed
    >>> fp.close()

    # create a temporary file using a context manager
    >>> with tempfile.TemporaryFile() as fp:
    ...     fp.write(b'Hello world!')
    ...     fp.seek(0)
    ...     fp.read()
    b'Hello world!'
    >>>
    # file is now closed and removed

    # create a temporary directory using the context manager
    >>> with tempfile.TemporaryDirectory() as tmpdirname:
    ...     print('created temporary directory', tmpdirname)
    >>>
    # directory and contents have been removed

## 11.6.2. 非推奨の関数と変数

一時ファイルを作成する歴史的な手法は、まず `mktemp()` 関数でファイル名を作り、その名前を使ってファイルを作成するというものでした。 残念ながらこの方法は安全ではありません。 なぜなら、`mktemp()` の呼び出しと最初のプロセスが続いてファイル作成を試みる間に、異なるプロセスがその名前でファイルを同時に作成するかもしれないからです。 解決策は二つのステップを同時に行い、ファイルをすぐに作成するというものです。 この方法は `mkstemp()` や上述している他の関数で使用されています。

`tempfile.``mktemp`(suffix='', prefix='tmp', dir=None)

  バージョン 2.3 で非推奨: 代わりに `mkstemp()` を使って下さい。

  呼び出し時には存在しなかった、ファイルの絶対パス名を返します。 prefix、suffix、dir 引数は `mkstemp()` のものと似ていますが、bytes のファイル名、`suffix=None`、そして `prefix=None` がサポートされていない点で異なります。

  警告

  この関数を使うとプログラムのセキュリティホールになる可能性があります。この関数がファイル名を返した後、あなたがそのファイル名を使って次に何かをしようとする段階に至る前に、誰か他の人間があなたを出し抜くことができてしまいます。 `mktemp()` の利用は、 `NamedTemporaryFile()` に `delete=False` 引数を渡すことで、簡単に置き換えることができます:

      >>> f = NamedTemporaryFile(delete=False)
      >>> f.name
      '/tmp/tmptjujjt'
      >>> f.write(b"Hello World!\n")
      13
      >>> f.close()
      >>> os.unlink(f.name)
      >>> os.path.exists(f.name)
      False