読者です 読者をやめる 読者になる 読者になる

Javaでテンポラリーファイルを使う。

Java
  • このメソッドの呼び出し以前に、このメソッドが返すファイルは存在しない。(上書きしない)
  • 現在の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
:
: