# 10.6. `tempfile` --- 一時的なファイルやディレクトリの生成

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

このモジュールを使うと、一時的なファイルやディレクトリを生成できます。このモジュールはサポートされている全てのプラットフォームで利用可能です。

バージョン 2.3 の Python では、このモジュールに対してセキュリティを高める為の見直しが行われました。現在では新たに 3 つの関数、 `NamedTemporaryFile()` 、 `mkstemp()` 、および `mkdtemp()` が提供されており、安全でない `mktemp()` を使いつづける必要をなくしました。このモジュールで生成されるテンポラリファイルはもはやプロセス番号を含みません; その代わり、6 桁のランダムな文字からなる文字列が使われます。

また、ユーザから呼び出し可能な関数は全て、テンポラリファイルの場所や名前を直接操作できるようにするための追加の引数をとるようになりました。もはや変数 tempdir および template を使う必要はありません。以前のバージョンとの互換性を維持するために、引数の順番は多少変です; 明確さのためにキーワード引数を使うことをお勧めします。

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

`tempfile.``TemporaryFile`([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None]]]]])

  一時的な記憶領域として使うことができるファイルライク(file-like)オブジェクトを返します。ファイルは `mkstemp()` を使って生成されます。このファイルは閉じられると (オブジェクトがガーベジコレクションされた際に、暗黙のうちに閉じられる場合を含みます) すぐに消去されます。Unix環境では、ファイルが生成されるとすぐにそのファイルのディレクトリエントリは除去されてしまいます。一方、他のプラットフォームではこの機能はサポートされていません; 従って、コードを書くときには、この関数で作成したテンポラリファイルをファイルシステム上で見ることができる、あるいはできないということをあてにすべきではありません。

  生成されたファイルを一旦閉じなくてもファイルを読み書きできるようにするために、 mode パラメータは標準で `'w+b'` に設定されています。ファイルに記録するデータが何であるかに関わらず全てのプラットフォームで一貫性のある動作をさせるために、バイナリモードが使われています。 bufsize の値は標準で `-1` で、これはオペレーティングシステムにおける標準の値を使うことを意味しています。

  dir 、 prefix および suffix パラメータは `mkstemp()` に渡されます。

  返されるオブジェクトは、POSIXプラットフォームでは本物のfileオブジェクトです。それ以外のプラットフォームではファイルライクオブジェクトが返され、 `file` 属性に本物のfileオブジェクトがあります。このファイルライクオブジェクトは、通常のファイルと同じように `with` 文で利用することができます。

`tempfile.``NamedTemporaryFile`([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None[, delete=True]]]]]])

  この関数はファイルがファイルシステム上で見ることができるよう保証されている点を除き、 `TemporaryFile()` と全く同じに働きます (Unixでは、ディレクトリエントリはunlinkされません)。 ファイル名は返されるファイルライクオブジェクトの `name` メンバから取得することができます。 このファイル名を使ってテンポラリファイルをもう一度開くとことができるかどうかは、プラットフォームによって異なります (Unixでは可能です; Windows NT以降では開けません)。 delete がtrue(デフォルト)の場合、ファイルは閉じられるとすぐに削除されます。

  返されるオブジェクトは、常にファイルライクオブジェクトです。このオブジェクトの `file` 属性が本物のfileオブジェクトになります。このファイルライクオブジェクトは、通常のファイルと同じように `with` 文を利用することができます。

  バージョン 2.3 で追加.

  バージョン 2.6 で追加: delete 引数

`tempfile.``SpooledTemporaryFile`([max_size=0[, mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None]]]]]])

  この関数は、ファイルサイズが max_size を超えるか、 `fileno()` メソッドが呼ばれるまでの間メモリ上で処理される以外は、 `TemporaryFile()` と同じです。 max_size を超えるか `fileno()` が呼ばれたとき、テンポラリファイルの内容がディスクに書き込まれ、その後の処理は `TemporaryFile()` で行われます。また、これの `truncate` メソッドは `size` 引数を受け付けません。

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

  返されるオブジェクトはファイルライクオブジェクトで、その `_file` 属性は、 `rollover()` が呼ばれたかどうかによって、 `StringIO` オブジェクトか、本物のファイルオブジェクトになります。このファイルライクオブジェクトは、通常のファイルオブジェクトと同じように、 `with` 文で利用することができます。

  バージョン 2.6 で追加.

`tempfile.``mkstemp`([suffix=''[, prefix='tmp'[, dir=None[, text=False]]]])

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

  `TemporaryFile()` と違って、 `mkstemp()` で生成されたファイルが用済みになったときにファイルを消去するのはユーザの責任です。

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

  prefix が指定された場合、ファイル名は指定されたプレフィクス(接頭文字列) で始まります; そうでない場合、標準のプレフィクスが使われます。

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

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

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

  バージョン 2.3 で追加.

`tempfile.``mkdtemp`([suffix=''[, prefix='tmp'[, dir=None]]])

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

  `mkdtemp()` によって作られたディレクトリとその内容が用済みになった時にそれを消去するのはユーザの責任です。

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

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

  バージョン 2.3 で追加.

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

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

  テンポラリファイルの絶対パス名を返します。このパス名は少なくともこの関数が呼び出された時点ではファイルシステム中に存在しなかったパス名です。 prefix 、 prefix 、 suffix 、および dir 引数は `mkstemp()` のものと同じです。

  警告

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

      >>> f = NamedTemporaryFile(delete=False)
      >>> f
      <open file '<fdopen>', mode 'w+b' at 0x384698>
      >>> f.name
      '/var/folders/5q/5qTPn6xq2RaWqk+1Ytw3-U+++TI/-Tmp-/tmpG7V1Y0'
      >>> f.write("Hello World!\n")
      >>> f.close()
      >>> os.unlink(f.name)
      >>> os.path.exists(f.name)
      False

このモジュールは一時的な名前の作成法を指定するグローバル変数を使います。それらの変数は上記のいずれかの関数を最初に呼び出した際に初期化されます。関数呼び出しを行うユーザはこれらの値を変更することができますが、推奨されていません。その代わりに関数に適切な引数を使ってください。

`tempfile.``tempdir`

  この値が `None` 以外に設定された場合、このモジュールで定義されている関数全ての dir 引数に対する標準の設定値となります。

  tempdir が設定されていないか `None` の場合、上記のいずれかの関数を呼び出した際は常に、Python は標準的なディレクトリ候補のリストを検索し、関数を呼び出しているユーザの権限でファイルを作成できる最初のディレクトリ候補を tempdir に設定します。リストは以下のようになっています:

  1. 環境変数 `TMPDIR` で与えられているディレクトリ名。
  2. 環境変数 `TEMP` で与えられているディレクトリ名。
  3. 環境変数 `TMP` で与えられているディレクトリ名。
  4. プラットフォーム依存の場所:
     - RiscOS では環境変数 `Wimp$ScrapDir` で与えられているディレクトリ名。
     - Windows ではディレクトリ `C:\TEMP` 、 `C:\TMP` 、 `\TEMP` 、および `\TMP` の順。
     - その他の全てのプラットフォームでは、 `/tmp` 、 `/var/tmp` 、および `/usr/tmp` の順。
  5. 最後の手段として、現在の作業ディレクトリ。

`tempfile.``gettempdir`()

  現在選択されている、テンポラリファイルを作成するためのディレクトリを返します。 `tempdir` が `None` でない場合、単にその内容を返します; そうでない場合には上で記述されている検索が実行され、その結果が返されます。

  バージョン 2.3 で追加.

`tempfile.``template`

  バージョン 2.0 で非推奨: 代わりに `gettempprefix()` を使ってください。

  この値に `None` 以外の値を設定した場合、 `mktemp()` が返すファイル名のディレクトリ部を含まない先頭部分 (プレフィクス) を定義します。ファイル名を一意にするために、 6 つのランダムな文字および数字がこのプレフィクスの後に追加されます。デフォルトのプレフィックスは `tmp` です。

  このモジュールの古いバージョンでは、 `os.fork()` を呼び出した後に `template` を `None` に設定することが必要でした; この仕様はバージョン 1.5.2 からは必要なくなりました。

`tempfile.``gettempprefix`()

  テンポラリファイルを生成する際に使われるファイル名の先頭部分を返します。この先頭部分にはディレクトリ部は含まれません。変数 template を直接読み出すよりもこの関数を使うことを勧めます。

  バージョン 1.5.2 で追加.