一時ディレクトリの取得、一時ファイルの作成について。

一時ディレクトリの取得

Path.GetTempPathメソッドを呼び出すと、戻り値で一時ディレクトリのパスを取得することができる。 このメソッドが返す一時ディレクトリは、環境変数の設定によって変わる(後述)。

一時ディレクトリ下のファイルパスを直接生成するメソッドはないので、Path.Combineメソッドを用いてPath.GetTempPathメソッドの戻り値と一時ファイル名を連結する必要がある。

一時ディレクトリを取得する・一時ファイルのパスを作成する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // 一時ディレクトリへのパスを取得する
    var tempdir = Path.GetTempPath();

    Console.WriteLine(tempdir);

    // 一時ディレクトリ下に配置するファイルtemp.txtのフルパスを作成する
    var tempfile = Path.Combine(Path.GetTempPath(), "temp.txt");

    Console.WriteLine(tempfile);
  }
}
一時ディレクトリを取得する・一時ファイルのパスを作成する
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' 一時ディレクトリへのパスを取得する
    Dim tempdir As String = Path.GetTempPath()

    Console.WriteLine(tempdir)

    ' 一時ディレクトリ下に配置するファイルtemp.txtのフルパスを作成する
    Dim tempfile As String = Path.Combine(Path.GetTempPath(), "temp.txt")

    Console.WriteLine(tempfile)
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
> csc test.cs
> test.exe
C:\Users\user\AppData\Local\Temp\
C:\Users\user\AppData\Local\Temp\temp.txt

> set TMP=D:\Temp\
> test.exe
D:\Temp\
D:\Temp\temp.txt
実行結果例(Ubuntu 14.04 + Mono 4.2)
$ mcs test.cs
$ mono test.exe
/tmp/
/tmp/temp.txt

$ export TMP=~/.tmp/
$ mono test.exe
/home/user/.tmp/
/home/user/.tmp/temp.txt

Path.GetTempPathメソッドの結果と環境変数の設定

Path.GetTempPathメソッドは、Windowsでは環境変数TMP(TMPが設定されていなければTEMP)に設定されているパスを返す。 TMPTEMPが変更されていなければ、通常%USERPROFILE%\AppData\Local\Tempを返す。 Linux等では/tmp/を返す。 ただし、環境変数TMPまたはTEMPが設定されている場合はそのディレクトリを返す。

Path.GetTempPathメソッドが返す値の順序を整理すると次のようになる。

Windowsの場合
  1. 環境変数TMP
  2. 環境変数TEMP
  3. レジストリキーHKEY_CURRENT_USER\EnvironmentTMP
  4. レジストリキーHKEY_CURRENT_USER\EnvironmentTEMP
  5. Windowsディレクトリ
Linux等の場合
  1. 環境変数TMP
  2. 環境変数TEMP
  3. /tmp/ディレクトリ

環境変数を設定していない場合、Linux等では全ユーザーが共用するディレクトリが一時ディレクトリとして返される点に注意する必要がある。

一時ファイルの作成

Path.GetTempFileNameメソッドを使うと、一時ディレクトリに一時ファイルを作成することができる。 GetTempFileNameメソッドを呼び出すと、拡張子が.tmpでサイズが0のファイルが作成される(このメソッドでは一時ファイル名のみを取得することはできない)。 そのため、一時ファイルを使用し終えたら必要に応じて削除する。

一時ファイルを作成してファイルにテキストを書き込む
using System;
using System.IO;

class Sample {
  static void Main()
  {
    string tempfile = null;

    try {
      // 一時ディレクトリ下に一時ファイルを作成し、そのファイルパスを取得する
      tempfile = Path.GetTempFileName();

      // 一時ファイルにテキストを書き込む
      File.WriteAllText(tempfile, "Hello, world!");
    }
    finally {
      // 一時ファイルが作成された場合、一時ファイルを使った処理が終了した時点で削除する
      if (tempfile != null && File.Exists(tempfile))
        File.Delete(tempfile);
    }
  }
}
一時ファイルを作成してファイルにテキストを書き込む
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    Dim tempfile As String = Nothing

    Try
      ' 一時ディレクトリ下に一時ファイルを作成し、そのファイルパスを取得する
      tempfile = Path.GetTempFileName()

      ' 一時ファイルにテキストを書き込む
      File.WriteAllText(tempfile, "Hello, world!")
    Finally
      ' 一時ファイルが作成された場合、一時ファイルを使った処理が終了した時点で削除する
      If tempfile IsNot Nothing AndAlso File.Exists(tempfile) Then
        File.Delete(tempfile)
      End If
    End Try
  End Sub
End Class

一時ファイルはGetTempPathメソッドで取得できるものと同じディレクトリに作成される。 また、GetTempFileNameメソッドは呼び出す度に異なるファイル名で一時ファイルを作成する。 作成されるファイル名は拡張子が.tmpとなる以外、具体的にどのようなファイル名となるかは定められていない点に注意。

複数の一時ファイルを作成する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // 一時ファイルを10個作成する
    for (var i = 0; i < 10; i++) {
      Console.WriteLine(Path.GetTempFileName());
    }
  }
}
複数の一時ファイルを作成する
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' 一時ファイルを10個作成する
    For i As Integer = 1 To 10
      Console.WriteLine(Path.GetTempFileName())
    Next
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
C:\Users\user\AppData\Local\Temp\tmp193D.tmp
C:\Users\user\AppData\Local\Temp\tmp193E.tmp
C:\Users\user\AppData\Local\Temp\tmp193F.tmp
C:\Users\user\AppData\Local\Temp\tmp1940.tmp
C:\Users\user\AppData\Local\Temp\tmp1941.tmp
C:\Users\user\AppData\Local\Temp\tmp1942.tmp
C:\Users\user\AppData\Local\Temp\tmp1943.tmp
C:\Users\user\AppData\Local\Temp\tmp1944.tmp
C:\Users\user\AppData\Local\Temp\tmp1954.tmp
C:\Users\user\AppData\Local\Temp\tmp1955.tmp
実行結果例(Ubuntu 14.04 + Mono 4.2, TMP=~/.tmp/)
/home/user/.tmp/tmp668418c6.tmp
/home/user/.tmp/tmp3a9becf7.tmp
/home/user/.tmp/tmp653c288.tmp
/home/user/.tmp/tmp3ed5990.tmp
/home/user/.tmp/tmp7d7ac222.tmp
/home/user/.tmp/tmp2be2804b.tmp
/home/user/.tmp/tmp5d65c9cf.tmp
/home/user/.tmp/tmp7ed97e69.tmp
/home/user/.tmp/tmp1b4c2b6a.tmp
/home/user/.tmp/tmp664e30cb.tmp

ランダムなファイル名の生成

一時ファイルの名前に用いる目的でランダムなファイル名を生成するには、Path.GetRandomFileNameメソッドを用いることができる。

このメソッドはPath.GetTempFileNameメソッドとは異なりファイル名のみを生成し、ファイル自体は生成しない。 一方、Path.GetRandomFileNameは拡張子もランダムな文字列となる。 拡張子をランダムにしたくない場合にはPath.ChangeExtensionメソッドを使って拡張子を変更する必要がある。 また生成されるファイル名にはディレクトリ名は含まれないので、一時ファイル名として用いる場合はPath.Combineメソッドでパスを結合する必要がある。

ランダムなファイル名で一時ファイルのパスを生成する
using System;
using System.IO;

class Sample {
  static void Main()
  {
    // ランダムなファイル名を5個生成する
    for (int i = 0; i < 5; i++) {
      Console.WriteLine(Path.GetRandomFileName());
    }
    Console.WriteLine();

    // 一時ディレクトリ下に配置するランダムなファイル名(拡張子.tmp)を5個生成する
    for (int i = 0; i < 5; i++) {
      // ランダムなファイル名を生成し、拡張子を.tmpに変更する
      var filename = Path.ChangeExtension(Path.GetRandomFileName(), ".tmp");

      // 生成したファイル名と一時ディレクトリのパスを結合して表示する
      Console.WriteLine(Path.Combine(Path.GetTempPath(), filename));
    }
  }
}
ランダムなファイル名で一時ファイルのパスを生成する
Imports System
Imports System.IO

Class Sample
  Shared Sub Main()
    ' 一時ファイルを5個作成する
    For i As Integer = 1 To 5
      Console.WriteLine(Path.GetRandomFileName())
    Next
    Console.WriteLine()

    ' 一時ディレクトリ下に配置するランダムなファイル名(拡張子.tmp)を5個生成する
    For i As Integer = 1 To 5
      ' ランダムなファイル名を生成し、拡張子を.tmpに変更する
      Dim filename As String = Path.ChangeExtension(Path.GetRandomFileName(), ".tmp")

      ' 生成したファイル名と一時ディレクトリのパスを結合して表示する
      Console.WriteLine(Path.Combine(Path.GetTempPath(), filename))
    Next
  End Sub
End Class
実行結果例(Windows 10 + .NET Framework 4.6)
ls1xc1gq.nup
r1prcdxe.zgz
hk5f2hnq.mnx
annuxtbh.zxa
eggtatzn.r0m

C:\Users\user\AppData\Local\Temp\4z4auewl.tmp
C:\Users\user\AppData\Local\Temp\rqtbpzil.tmp
C:\Users\user\AppData\Local\Temp\5l0g52sc.tmp
C:\Users\user\AppData\Local\Temp\4o4r2pdh.tmp
C:\Users\user\AppData\Local\Temp\tcw0zr0w.tmp
実行結果例(Ubuntu 14.04 + Mono 4.2, TMP=~/.tmp/)
h6ud5fvv.lvl
7dt3v9ck.93k
add7fbiw.oq2
h15fyqqp.3gn
nay4h7dt.y2q

/home/user/.tmp/wa1ejwlj.tmp
/home/user/.tmp/0fhl2bwf.tmp
/home/user/.tmp/pwd3nq37.tmp
/home/user/.tmp/9gpeht67.tmp
/home/user/.tmp/h1zusddc.tmp

この例では生成したファイル名が衝突する可能性があるため、実際に一時ファイル名として使用する場合は、すでにファイル名が使用されていないかを調べる必要がある。