[java] StandardOpenOption.DELETE_ON_CLOSE

StandardOpenOption.DELETE_ON_CLOSE

java.nio.fileのStandardOpenOptionにはDELETE_ON_CLOSEという定数が定義されている。
この定数をファイルのオープン時のオプションとして利用すると、ファイルをクローズした時に自動的にファイルが削除される。
下記の通り利用する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class DeleteOnCloseTest {
    public static void main(String[] args) {
        Path file1 = Paths.get("C:", "file1.txt");
        try (BufferedWriter writer = Files.newBufferedWriter(file1, StandardCharsets.UTF_8,
             StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING,
             StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE)) {
            writer.write("test1-1\n");
            writer.write("test1-2\n");
            writer.write("test1-3\n");
            System.out.println("1.file1 exists? " + Files.exists(file1));
        } catch (Exception e) {
            System.out.println("create file failed. " + e.toString());
        }
        System.out.println("2.file1 exists? " + Files.exists(file1));
    }
}

実行すると、

1.file1 exists? true
2.file1 exists? false

と出力される。
中間ファイルとして利用するのに便利なのかもしれないが、
もし、出力中に想定外のExceptionが発生した場合は、原因追求のためにファイルは削除せずに残しておきたい。
したがって、こういう使い方はあまりしない気がする。

どちらかと言えば、読み込みオープンの時に指定できれば、中間ファイルを読んで、読み終わったら削除できるので便利な気がする。
しかし、このオペレーションはサポートされていない。
Files.newBufferedReaderではOpenOptionが指定できないし、
Files.newInputSreamでOpenOptionを指定しても下記の通り例外が発生する。

1
java.lang.UnsupportedOperationException: 'DELETE_ON_CLOSE' not allowed

ちなみに、この自動削除の仕組みを利用してプログラムを作成するのであれば、
中間ファイル名は自動でjavaに決めてもらった方が簡単な気がする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package test.java;

import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class DeleteOnCloseTest {
    public static void main(String[] args) {
        Path file3 = null;
        try {
            file3 = Files.createTempFile(null, null);
        } catch (Exception e) {
            System.out.println("create temp file failed. " + e.toString());
            throw new RuntimeException(e);
        }
        System.out.println("work file name:" + file3.toString());
        try (BufferedWriter writer = Files.newBufferedWriter(file3, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE)) {
            writer.write("test3-1\n");
            writer.write("test3-2\n");
            writer.write("test3-3\n");
            System.out.println("1.file3 exists? " + Files.exists(file3));
        } catch (Exception e) {
            System.out.println("write file failed. " + e.toString());
        }
        System.out.println("2.file3 exists? " + Files.exists(file3));
    }
}

実行すると、下記の通り出力される。

work file name:C:\Users\xxxxx\AppData\Local\Temp\6712414364776398896.tmp
1.file3 exists? true
2.file3 exists? false

Files.createTempFileで一時ファイルを作成できる。第一引数は中間ファイルのプレフィックス。第二引数は中間ファイルのサフィックス。
どうせ、見えずに消えてしまうファイルなので、どちらの引数もnullを指定している。
これで、ファイル名の重複を気にせず、中間ファイルを作成できる。

また、これらの処理がバッチ処理で、javaのプロセスが適宜終了するのであれば、下記の通りファイルに削除設定をしておいても、プロセス終了時に中間ファイルが削除される。

1
2
Path file = Paths.get("workfile");
file.toFile().deleteOnExit();
同じタグの記事
同じカテゴリの記事

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA