DirectoryNotEmptyException是Files.delete()删除非空目录时抛出的异常,因其仅支持空目录或文件删除;正确方案是用Files.walkFileTree()递归删除或借助Commons IO/Guava工具类。
java中directorynotemptyexception是files.delete()方法在尝试删除非空目录时抛出的异常,它属于java.nio.file包,表示该目录下还有文件或子目录,无法直接删除。
为什么会出现这个异常?
因为Files.delete()只支持删除空目录或单个文件。它不会递归清理子内容,和Linux里的rmdir命令行为一致(不是rm -r)。一旦目标路径是个非空文件夹,就会立即抛出DirectoryNotEmptyException。
正确删除非空目录的两种主流方式
推荐使用Files.walkFileTree()配合自定义SimpleFileVisitor,这是NIO.2的标准、安全、可中断的递归删除方案:
- 先从最深层的文件开始删除(
visitFile),再逐级向上删空目录(postVisitDirectory) - 自动处理符号链接、权限不足等边界情况,可重写对应方法增强容错
- 避免手动递归调用导致栈溢出或遗漏
示例代码片段:
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (exc == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
throw exc;
}
});
更简洁的替代方案:使用Files.deleteIfExists() + 手动递归(慎用)
如果项目已引入Apache Commons IO或Guava,可以直接调用封装好的工具方法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- Commons IO:
FileUtils.deleteDirectory(file)(会自动处理非空) - Guava:
MoreFiles.deleteRecursively(path)(返回void,失败抛异常)
不建议自己写“先list再for循环delete”的递归逻辑——容易漏删、忽略异常、不支持大深度目录,且不符合NIO设计哲学。
预防比修复更重要:删除前先判断
若业务逻辑允许跳过非空目录,可在删除前快速检查:
-
Files.isDirectory(path) && !Files.list(path).findAny().isPresent()→ 空目录 - 或者用
Files.exists(path) && !Files.isRegularFile(path)确认是目录,再决定是否走递归流程
注意:Files.list()需try-with-resources防止资源泄漏,生产环境建议配合超时或深度限制。

















