CodeGym /课程 /JAVA 25 SELF /处理临时文件和目录

处理临时文件和目录

JAVA 25 SELF
第 40 级 , 课程 3
可用

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(PathFiles),就需要手动删除。

删除临时目录

只有在目录为空时才能删除临时目录:

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() 并做好错误处理。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION