362. Java IO API - 操作文件和目录

0 阅读2分钟

362. Java IO API - 操作文件和目录

操作文件和目录是编写文件 I/O 程序时最常见的任务之一。Java NIO 提供了功能强大的 Files 类和 Path 接口来简化这些操作。


✅ 1. 检查文件或目录是否存在

Path 实例本身只是一个路径字符串的封装,不代表真实存在的文件。要检查路径对应的文件是否真的存在,需要访问文件系统:

Files.exists(path)       // 检查是否存在
Files.notExists(path)    // 检查是否明确不存在

⚠️ 注意: !Files.exists(path)Files.notExists(path) 不等价! 三种可能的返回结果:

exists(path)notExists(path)含义
truefalse文件存在
falsetrue文件不存在
falsefalse无法判断(权限问题或IO错误)
示例代码:
Path path = Paths.get("/path/to/file.txt");

if (Files.exists(path)) {
    System.out.println("✅ 文件存在");
} else if (Files.notExists(path)) {
    System.out.println("❌ 文件不存在");
} else {
    System.out.println("⚠️ 无法判断文件状态(可能是权限问题)");
}

🔒 2. 检查文件的访问权限

你可以使用以下方法来检测文件是否可读、可写、可执行:

Files.isReadable(path)
Files.isWritable(path)
Files.isExecutable(path)

这些方法非常适合在文件处理前进行权限校验,例如:

示例:检查是否是一个可读并可执行的常规文件
Path file = Paths.get("run.sh");

boolean isExecutable = Files.isRegularFile(file)
                     && Files.isReadable(file)
                     && Files.isExecutable(file);

if (isExecutable) {
    System.out.println("✅ 可执行的脚本文件");
} else {
    System.out.println("❌ 文件不存在或不可执行");
}

🔐 注意:TOCTTOU 问题(Time-of-check to time-of-use) 在检查完权限之后立刻使用文件并不安全,因为文件状态在检查和使用之间可能发生变化。 建议直接尝试操作文件,并捕获异常来处理错误。


🔗 3. 判断两个路径是否引用同一个文件

在支持**符号链接(symbolic links)**的系统中,不同路径可能指向同一个文件。

此时可以使用:

Files.isSameFile(path1, path2)

该方法会解析符号链接并访问底层文件系统,判断两个 Path 是否指向同一个实体。

示例代码:
Path p1 = Paths.get("/home/user/docs/report.txt");
Path p2 = Paths.get("/home/user/shortcut/report.txt");

if (Files.isSameFile(p1, p2)) {
    System.out.println("✅ 两个路径引用同一个文件");
} else {
    System.out.println("❌ 路径对应的文件不同");
}

💡 若路径不存在,将抛出 IOException,建议使用 try-catch 块包裹调用。


📌 实战提示

操作需求推荐方法
检查文件是否存在Files.exists(path)
检查是否可读/写/执行Files.isReadable(path)
比较两个路径是否指向同一文件Files.isSameFile(path1, path2)
文件是否是常规文件Files.isRegularFile(path)
避免 TOCTTOU 安全问题使用 try-catch 替代提前检查权限

✅ 总结

  • Path 是语法结构,不代表真实文件。
  • 使用 Files.exists()Files.notExists() 与文件系统交互。
  • 使用 Files.isReadable() 等方法判断权限。
  • 使用 Files.isSameFile() 判断路径指向是否一致。
  • 编写健壮程序应避免“检查后使用”的 TOCTTOU 漏洞,建议直接操作并处理异常。