1. 创建临时文件:Files.createTempFile
临时文件用于存放中间数据、缓存,或任何不打算长期保留的结果。通常,它们的生命周期与程序一致,或者在不再需要这些数据时被删除。
最常见的用法:下载大文件时(先下载到临时目录,再移到目标位置)、缓存可以重新计算或重新获取的信息、在处理海量数据时存放中间结果,以及在程序的不同组件或线程之间交换数据。另一个常见场景是测试:把数据写到临时文件比把工作目录弄乱要更合适。
可以把临时文件看作程序的草稿。它们不面向最终用户,但没有它们很多工作难以开展。
在 Java 中创建这样的文件非常简单——几乎一行代码即可。为此可以使用 Files.createTempFile 方法。
简单示例
import java.nio.file.*;
public class TempFileExample {
public static void main(String[] args) throws Exception {
// 创建一个前缀为 "myapp_"、后缀为 ".tmp" 的临时文件
Path tempFile = Files.createTempFile("myapp_", ".tmp");
System.out.println("已创建临时文件: " + tempFile);
// 可以向其中写入数据
Files.writeString(tempFile, "这是临时数据");
// 再读回来
String data = Files.readString(tempFile);
System.out.println("内容: " + data);
}
}
发生了什么?
- 文件会被创建在系统临时目录中(在 Linux 通常是 "/tmp",在 Windows 通常是 "C:\\Users\\<用户名>\\AppData\\Local\\Temp")。
- 文件名类似于 "myapp_1234567890.tmp"。
- 文件已经存在于磁盘上,可以像普通文件一样操作。
方法参数
- 第一个参数——前缀(例如 "myapp_")。
- 第二个参数——后缀(例如,".tmp")。如果不指定,则默认为 ".tmp"。
- 如果两个参数都为 null,则使用默认命名。
文件保存到哪里?
默认情况下,文件保存在系统临时目录。但你也可以指定自定义目录:
Path tempDir = Paths.get("my_temp_folder");
Files.createDirectories(tempDir); // 若不存在则创建
Path tempFile = Files.createTempFile(tempDir, "prefix_", ".txt");
2. 创建临时目录:Files.createTempDirectory
有时不仅需要一个临时文件,还需要一个临时目录——例如用于解压缩归档文件,或暂存大量文件。
示例
import java.nio.file.*;
public class TempDirExample {
public static void main(String[] args) throws Exception {
// 创建前缀为 "work_" 的临时目录
Path tempDir = Files.createTempDirectory("work_");
System.out.println("临时目录: " + tempDir);
// 可以在其中创建文件
Path fileInTempDir = Files.createTempFile(tempDir, "file_", ".dat");
System.out.println("内部的临时文件: " + fileInTempDir);
}
}
特点:
- 目录名大致形如:"work_1234567890"。
- 默认位于系统临时目录,但也可以指定任意其他位置。
指定目录
Path baseDir = Paths.get("my_temp_work");
Files.createDirectories(baseDir);
Path tempDir = Files.createTempDirectory(baseDir, "session_");
3. 删除临时文件和目录
这正是 Java 中的一个主要“坑点”:临时文件和目录 并不会自动删除!如果你不清理,它们会一直留在磁盘上,可能“陪伴”你很多年(或直到系统下一次清理)。
如何删除临时文件?
- 手动:在用完文件后调用 Files.delete(...) 或 Files.deleteIfExists(...)。
- 在程序结束时:可以使用老办法 File.deleteOnExit(),但它只适用于 File,而不是 Path。
示例:删除临时文件
import java.nio.file.*;
public class TempFileDeleteExample {
public static void main(String[] args) throws Exception {
Path tempFile = Files.createTempFile("demo_", ".tmp");
System.out.println("已创建: " + tempFile);
// ... 使用该文件
// 删除文件
Files.deleteIfExists(tempFile);
System.out.println("已删除: " + tempFile);
}
}
使用 deleteOnExit()
import java.io.File;
public class DeleteOnExitDemo {
public static void main(String[] args) throws Exception {
File tempFile = File.createTempFile("legacy_", ".tmp");
System.out.println("已创建: " + tempFile);
// 在 JVM 退出时标记该文件为删除
tempFile.deleteOnExit();
}
}
注意!
方法 deleteOnExit() 只适用于 File,不适用于 Path。如果你使用现代 API(Path 和 Files),就需要手动删除。
删除临时目录
只有在目录为空时才能删除临时目录:
Files.delete(tempDir); // 如果目录非空将抛出异常
如果目录中还有文件——先删除这些文件,再删除目录。通常会写一个小型的递归方法来完成这件事。
4. 实践建议
临时文件放在哪里?
系统临时目录:
默认情况下优先使用它,除非有特殊需求。可以这样获取路径:
String tempDir = System.getProperty("java.io.tmpdir");
System.out.println("系统临时目录: " + tempDir);
自定义目录:
如果你更关注安全或组织性——请创建单独的目录(例如在应用目录内)。
安全性
- 不要把临时文件存放在公共目录中——尤其当其中可能包含敏感信息时。
- 使用后清理临时文件——否则它们会不断累积并占用磁盘空间。
出现错误时的清理
如果程序执行过程中发生错误,不要忘记删除临时文件。为此,使用 try-finally 非常方便:
Path tempFile = Files.createTempFile("task_", ".tmp");
try {
// 使用该文件
} finally {
Files.deleteIfExists(tempFile);
}
临时文件与测试
在测试中常用临时文件和目录来隔离数据。测试结束后——务必删除所有创建的内容!
5. 示例:用于数据处理的临时工作目录
假设你在编写一个处理压缩包并临时解压文件的程序。为此,创建一个临时目录会很方便,并在处理完成后将其删除。
import java.nio.file.*;
import java.io.IOException;
public class TempWorkDirExample {
public static void main(String[] args) throws IOException {
// 创建临时目录
Path tempWorkDir = Files.createTempDirectory("unzip_");
System.out.println("临时工作目录: " + tempWorkDir);
try {
// 此处可以是解压缩逻辑
Path tempFile = Files.createTempFile(tempWorkDir, "file_", ".txt");
Files.writeString(tempFile, "用于处理的临时数据");
// ... 处理文件
} finally {
// 删除目录中的所有文件以及目录本身
Files.walk(tempWorkDir)
.sorted((a, b) -> b.compareTo(a)) // 先文件,后目录
.forEach(path -> {
try {
Files.deleteIfExists(path);
} catch (IOException ex) {
System.err.println("无法删除 " + path + ": " + ex.getMessage());
}
});
System.out.println("已删除临时目录及其文件。");
}
}
}
请注意:
先删除所有文件,再删除目录本身。排序是为了避免在删除目录内容之前就尝试删除目录。
6. 使用临时文件的常见错误
错误 1:忘记删除临时文件或目录。 最常见的问题是临时文件残留在磁盘上、不断累积,久而久之导致系统变得杂乱无章。对服务器应用和长时间运行的进程尤其致命。
错误 2:对 Path 使用 deleteOnExit()。 方法 deleteOnExit() 只适用于类 File,不适用于 Path。如果你使用现代 API,就必须手动删除。
错误 3:尝试用 Files.delete 删除非空目录。 方法 Files.delete() 只能删除空目录。如果目录内仍有内容——会抛出异常。要删除非空目录,请递归遍历并删除所有文件。
错误 4:在项目工作目录下创建临时文件。 这可能导致误删重要文件或造成混乱。最好使用系统临时目录,或为应用的临时文件单独建一个目录。
错误 5:删除临时文件时不处理异常。 如果文件已被删除或被占用,删除操作可能抛出异常。请使用 Files.deleteIfExists() 并做好错误处理。
GO TO FULL VERSION