Javaでテンポラリーファイルを使う。
- File.createTempFile(...)
- Google Code Search: File.createTempFile
- http://www.exampledepot.com/egs/java.io/CreateTempFile.html
- このメソッドの呼び出し以前に、このメソッドが返すファイルは存在しない。(上書きしない)
- 現在のVM上では、同じパスを二度と返さない。
ということがJavaDocに書いてある。異なるVM上だと上書きする可能性があるのかどうかが、よくわからない。
→ 調べた。ソースを見ると、nativeメソッドのjava.io.FileSystem#createFileExclusively() に依存している。同じメソッドを内部で使用する、File#createNewFile()の説明には、ファイルシステム上でアトミックに実行されるとある。なんとなく大丈夫そう。
prefixの後の内部文字列部分(カウンタ)は、初期値がランダムに生成されていた。
private static File generateFile(String prefix, String suffix, File dir) throws IOException { if (counter == -1) { counter = new Random().nextInt() & 0xffff; } counter++; return new File(dir, prefix + Integer.toString(counter) + suffix); }
実験用のコード。
import java.io.File; public class TrialCode { public static final void main(String[] args) throws Exception { System.out.println(System.getProperty("java.io.tmpdir")); for (int i = 0 ; i < 5; i++) { String prefix = "java_tmpfile_trial"; String suffix = null; File f = null; try { // ファイル名は「(調整されたprefix) + (内部文字5文字以上) + (suffix or .tmp)」 f = File.createTempFile(prefix, suffix); System.out.println(f.getCanonicalPath()); System.out.println("exists?:" + f.exists()); } finally { // File#deleteOnExit()じゃなくても普通に消せる。 if (f != null) { System.out.println("delete?:" + f.delete()); } } } } }
Windows上での実行結果。
C:\Documents and Settings\****\Local Settings\Temp\java_tmpfile_trial6305.tmp exists?:true delete?:true C:\Documents and Settings\****\Local Settings\Temp\java_tmpfile_trial6306.tmp exists?:true delete?:true : :