363. Java IO API - 删除文件和目录
在文件操作中,删除是一个非常常见但需要小心处理的操作,尤其在涉及目录和符号链接时更是如此。
✅ 1. 删除的基本规则
- 文件(file):可以直接删除。
- 目录(directory):必须为空,否则删除会失败。
- 符号链接(symbolic link):删除的是链接本身,不是它指向的目标。
✂️ 2. 删除文件的两种方式
Java 提供了两种方式来删除文件或目录:
方法一:Files.delete(Path path)
此方法用于强制删除,如果删除失败会抛出异常,适合你希望清楚了解失败原因的场景。
示例代码:
try {
Files.delete(Paths.get("data.txt"));
System.out.println("✅ 文件删除成功!");
} catch (NoSuchFileException e) {
System.err.println("❌ 文件不存在:" + e.getMessage());
} catch (DirectoryNotEmptyException e) {
System.err.println("📂 目录不为空,无法删除:" + e.getMessage());
} catch (IOException e) {
System.err.println("⚠️ 删除失败,可能是权限问题:" + e.getMessage());
}
方法二:Files.deleteIfExists(Path path)
此方法删除文件,但如果文件不存在也不会抛出异常,返回值为 true 表示删除成功,false 表示文件本来就不存在。
示例代码:
Path path = Paths.get("temp.log");
try {
boolean deleted = Files.deleteIfExists(path);
if (deleted) {
System.out.println("✅ 文件已删除");
} else {
System.out.println("ℹ️ 文件原本就不存在");
}
} catch (IOException e) {
System.err.println("⚠️ 删除失败:" + e.getMessage());
}
✅ 应用场景建议:
| 场景 | 建议方法 |
|---|---|
| 你希望严格处理删除失败并报告原因 | Files.delete(path) |
| 你只是想安静地尝试删除,不管是否存在 | Files.deleteIfExists(path) |
| 多线程环境,避免竞争删除时抛异常 | deleteIfExists 更合适 |
🧠 补充提示:递归删除目录
标准 API 没有提供递归删除目录的方法,如果你想要删除非空目录,需要自己遍历子文件并逐个删除。例如:
void deleteRecursively(Path path) throws IOException {
if (Files.isDirectory(path)) {
try (DirectoryStream<Path> entries = Files.newDirectoryStream(path)) {
for (Path entry : entries) {
deleteRecursively(entry);
}
}
}
Files.delete(path);
}
❗ 安全注意事项
- 删除操作不可恢复,请务必确认路径。
- 删除目录前应检查是否为空,或考虑是否应该递归删除。
- 文件可能正在被其他进程使用,导致删除失败。
- 有些系统目录(如 Windows 的
C:\Windows)根本不允许删除,尝试会抛异常。
📌 总结小表
| 方法 | 行为 | 是否抛出异常 |
|---|---|---|
Files.delete(path) | 删除文件/空目录 | 是(失败即抛) |
Files.deleteIfExists() | 删除,文件不存在也不报错 | 是(但文件不存在不抛) |
| 递归删除目录 | 自定义实现遍历目录后逐个删除 | 是(建议封装) |