临时文件与目录
临时文件在上传下载、报表生成、压缩解压、批处理、中间结果落盘等场景中非常常见。临时文件看似简单,但如果管理不当,容易造成磁盘被打满、敏感数据泄漏或并发文件名冲突。
# 1. 创建临时文件
推荐使用 Files.createTempFile:
Path tempFile = Files.createTempFile("upload-", ".tmp");
它会在系统默认临时目录中创建文件,并保证文件名尽量唯一。
也可以指定目录:
Path tempDir = Path.of("/data/tmp");
Path tempFile = Files.createTempFile(tempDir, "report-", ".xlsx");
# 2. 创建临时目录
Path tempDir = Files.createTempDirectory("batch-");
适合一次任务需要多个中间文件的场景。
# 3. 临时文件使用示例
Path tempFile = Files.createTempFile("export-", ".csv");
try {
try (BufferedWriter writer = Files.newBufferedWriter(tempFile, StandardCharsets.UTF_8)) {
writer.write("id,name");
writer.newLine();
writer.write("1,Alice");
}
// 上传、移动或返回给调用方
} finally {
Files.deleteIfExists(tempFile);
}
关键点是使用 finally 或任务清理机制删除临时文件。
# 4. deleteOnExit 的问题
File.deleteOnExit() 可以注册 JVM 退出时删除文件:
file.deleteOnExit();
但生产环境不推荐大量使用:
- 只有 JVM 正常退出时才执行。
- 长时间运行的服务中,临时文件会一直保留到进程退出。
- JVM 内部会维护待删除文件列表,大量注册可能占用内存。
服务端程序更应该主动清理。
# 5. 原子写文件
写重要文件时,常见做法是先写临时文件,再原子移动到目标位置。
Path target = Path.of("config.json");
Path temp = Files.createTempFile(target.getParent(), "config-", ".tmp");
try {
Files.writeString(temp, json, StandardCharsets.UTF_8);
Files.move(temp, target,
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.ATOMIC_MOVE);
} catch (IOException e) {
Files.deleteIfExists(temp);
throw e;
}
这样可以减少“目标文件写到一半失败”的风险。
ATOMIC_MOVE 是否支持取决于文件系统,不支持时会抛出异常。
# 6. 安全注意点
- 临时文件不要使用可预测文件名。
- 不要把敏感数据长时间留在临时目录。
- 共享服务器上要注意文件权限。
- 上传文件落临时目录前要限制大小。
- 定期清理历史临时文件。
# 专家实践清单
| 检查项 | 建议 | 风险 |
|---|---|---|
| 命名 | 使用 Files.createTempFile | 手写文件名可能冲突 |
| 权限 | 限制敏感临时文件权限 | 共享机器泄露数据 |
| 容量 | 限制上传和中间文件大小 | 临时目录被打满 |
| 清理 | finally 或后台清理 | 长期堆积占满磁盘 |
| 原子发布 | 临时文件 + Files.move | 避免正式文件半写入 |
可靠临时文件流程:
创建临时文件
│
▼
写入和校验
│
├─ 成功:原子移动到目标路径
└─ 失败:删除临时文件
# Tips 快问快答
Q:为什么不要自己拼临时文件名?
A:容易冲突或被路径注入,createTempFile 能生成唯一名称。
Q:临时文件会自动删除吗?
A:不一定。应显式清理,deleteOnExit 不适合长期运行服务大量使用。
Q:deleteOnExit 有什么风险?
A:记录会保存在 JVM 内存中,长期服务大量注册可能造成内存压力。
Q:临时目录可以存敏感数据吗? A:可以但要控制权限、加密和清理,避免共享环境泄露。
Q:上传文件为什么常先落临时目录? A:便于校验大小、类型、病毒扫描和失败清理。
Q:临时文件如何帮助可靠写入? A:先写临时文件,完成后原子移动,避免目标文件半更新。
Q:清理临时文件应该放在哪里? A:失败路径放 finally,历史遗留可用后台任务定期清理。
Q:临时目录满了会怎样? A:新文件创建或写入失败,可能影响上传、导出、编译等功能。
# 7. 总结
临时文件不是随手创建、用完不管的文件。可靠的临时文件处理应具备唯一命名、异常清理、权限控制、容量限制和定期清理机制。重要文件写入可以使用“临时文件 + 原子移动”提高一致性。