Java NIO.2 API提供了对使用临时文件夹/文件的支持。例如,我们可以轻松地找到临时文件夹/文件的默认位置,如下所示:

Java

String defaultBaseDir = System.getProperty("java.io.tmpdir");

通常,在Windows中,默认的临时文件夹为 C:Temp , %Windows%Temp 或每个用户所在的临时目录 Local SettingsTemp (此位置通常由TEMP 环境变量控制 )。

在Linux / Unix中,全局临时目录为 /tmp 和 /var/tmp 。前一行代码将返回默认位置,具体取决于操作系统。接下来,我们将学习如何创建一个临时文件夹/文件。

创建一个临时文件夹/文件

创建临时文件夹可以使用以下方法完成:

· Path createTempDirectory (Path dir, String prefix, FileAttribute<?>... attrs)

这是类中的一种 static方法 Files ,可以按如下方式使用:

· 让我们在操作系统的默认位置创建一个没有前缀的临时文件夹:

Java

1
// C:UsersAnghelAppDataLocalTemp8083202661590940905
2
Path tmpNoPrefix = Files.createTempDirectory(null);

让我们在操作系统的默认位置创建一个带有自定义前缀的临时文件夹:

Java

1
// C:UsersAnghelAppDataLocalTemplogs_5825861687219258744
2
String customDirPrefix = "logs_";
3
Path tmpCustomPrefix = Files.createTempDirectory(customDirPrefix);

让我们在带有自定义前缀的自定义位置中创建一个临时文件夹:

Java

1
// D:tmplogs_10153083118282372419
2
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
3
String customDirPrefix = "logs_";
4
Path tmpCustomLocationAndPrefix = Files.createTempDirectory(customBaseDir, customDirPrefix);

创建临时文件可以通过以下方式完成:

· Path createTempFile (Path dir, String prefix, String suffix, FileAttribute<?>... attrs

这是类中的一种static方法Files ,可以按如下方式使用:

· 让我们在操作系统的默认位置创建一个没有前缀和后缀的临时文件:

Java

1
// C:UsersAnghelAppDataLocalTemp16106384687161465188.tmp
2
Path tmpNoPrefixSuffix = Files.createTempFile(null, null);

让我们在操作系统的默认位置创建一个带有自定义前缀和后缀的临时文件:

Java

1
// C:UsersAnghelAppDataLocalTemplog_402507375350226.txt
2
String customFilePrefix = "log_";
3
String customFileSuffix = ".txt";
4
Path tmpCustomPrefixAndSuffix = Files.createTempFile(customFilePrefix, customFileSuffix);

让我们在带有自定义前缀和后缀的自定义位置中创建一个临时文件:

Java

1
// D:tmplog_13299365648984256372.txt
2
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
3
String customFilePrefix = "log_";
4
String customFileSuffix = ".txt";
5
Path tmpCustomLocationPrefixSuffix 
6
 = Files.createTempFile(customBaseDir, customFilePrefix, customFileSuffix);

接下来,我们将研究删除临时文件夹/文件的不同方法。

通过关机挂钩删除临时文件夹/文件

删除临时文件夹/文件是可以由操作系统或专用工具完成的任务。但是,有时,我们需要以编程方式进行控制,并基于不同的设计考虑因素删除文件夹/文件。

该问题的解决方案依赖于可通过该方法实现的关机挂钩机制 Runtime.getRuntime().addShutdownHook() 。每当我们需要在JVM关闭之前立即完成某些任务(例如,清理任务)时,此机制就很有用。它作为Java线程实现,run() 当JVM在关闭时执行shutdown-hook时,将调用其 方法。如下代码所示:

Java

1
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
2
String customDirPrefix = "logs_";
3
String customFilePrefix = "log_";
4
String customFileSuffix = ".txt";
5
6
try {
7
 Path tmpDir = Files.createTempDirectory(customBaseDir, customDirPrefix);
8
 Path tmpFile1 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
9
 Path tmpFile2 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
10
11
 Runtime.getRuntime().addShutdownHook(new Thread() {
12
13
 @Override
14
 public void run() {
15
 try (DirectoryStream<Path> ds = Files.newDirectoryStream(tmpDir)) {
16
 for (Path file: ds) {
17
 Files.delete(file);
18
 }
19
20
 Files.delete(tmpDir);
21
 } catch (IOException e) {
22
 ...
23
 }
24
 }
25
 });
26
27
 //simulate some operations with temp file until delete it
28
 Thread.sleep(10000);
29
} catch (IOException | InterruptedException e) {
30
 ...
31
}

通过deleteOnExit()删除临时文件夹/文件

删除临时文件夹/文件的另一种解决方案依赖于该 File.deleteOnExit()方法。通过调用此方法,我们可以注册删除文件夹/文件。JVM关闭时,将执行删除操作:

Java

1
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
2
String customDirPrefix = "logs_";
3
String customFilePrefix = "log_";
4
String customFileSuffix = ".txt";
5
6
try {
7
 Path tmpDir = Files.createTempDirectory(customBaseDir, customDirPrefix);
8
 System.out.println("Created temp folder as: " + tmpDir);
9
 Path tmpFile1 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
10
 Path tmpFile2 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
11
12
 try (DirectoryStream<Path> ds = Files.newDirectoryStream(tmpDir)) {
13
 tmpDir.toFile().deleteOnExit();
14
15
 for (Path file: ds) { 
16
 file.toFile().deleteOnExit();
17
 }
18
 } catch (IOException e) {
19
 ...
20
 }
21
22
 // simulate some operations with temp file until delete it
23
 Thread.sleep(10000);
24
} catch (IOException | InterruptedException e) {
25
 ...
26
}

通过DELETE_ON_CLOSE删除临时文件

删除临时文件所依赖的另一个解决方案 StandardOpenOption.DELETE_ON_CLOSE (在关闭流时删除该文件)。例如,下面的代码段通过createTempFile() 方法创建一个临时文件,并为该文件打开一个DELETE_ON_CLOSE 显式指定的缓冲写流:

Java

1
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
2
String customFilePrefix = "log_";
3
String customFileSuffix = ".txt";
4
Path tmpFile = null;
5
6
try {
7
 tmpFile = Files.createTempFile(
8
 customBaseDir, customFilePrefix, customFileSuffix);
9
} catch (IOException e) {
10
 ...
11
}
12
13
try (BufferedWriter bw = Files.newBufferedWriter(tmpFile,
14
 StandardCharsets.UTF_8, StandardOpenOption.DELETE_ON_CLOSE)) {
15
16
 //simulate some operations with temp file until delete it
17
 Thread.sleep(10000);
18
} catch (IOException | InterruptedException e) {
19
 ...
20
}