推荐使用 Files.walk() 遍历指定目录下的所有文件,它简洁安全、支持函数式风格,自动处理符号链接和异常;Files.find() 适合带谓词的复杂筛选;传统 File.list()/listFiles() 易出错且功能受限。

Java 中遍历指定目录下的所有文件,推荐使用 Files.walk()(Java 8+),它简洁、安全、支持函数式风格,且自动处理符号链接和异常边界情况。
用 Files.walk() 递归遍历所有文件(推荐)
这是最现代、最常用的方式,返回一个 Stream,可轻松过滤文件/目录、跳过异常路径:
- 只遍历普通文件(排除目录):
Files.walk(Paths.get("D:/myfolder"))
.filter(Files::isRegularFile)
.forEach(System.out::println); - 限制深度(比如只查 2 层):
Files.walk(Paths.get("D:/myfolder"), 2)
.filter(Files::isRegularFile)
.forEach(System.out::println); - 捕获访问异常(如权限不足):
try {
Files.walk(Paths.get("D:/myfolder"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
用 Files.find() 按条件查找(适合带谓词的筛选)
当需要结合文件属性(如修改时间、大小、扩展名)做复杂判断时更灵活:
- 查找所有 .log 文件:
Files.find(Paths.get("D:/logs"),
Integer.MAX_VALUE,
(path, attrs) -> path.toString().endsWith(".log"))
.forEach(System.out::println); - 查找最近 7 天修改的 .txt 文件:
long sevenDaysAgo = System.currentTimeMillis() - 7L * 24 * 3600 * 1000;
Files.find(Paths.get("D:/docs"), Integer.MAX_VALUE,
(path, attrs) -> path.toString().endsWith(".txt") &&
attrs.lastModifiedTime().toMillis() > sevenDaysAgo)
.forEach(System.out::println);
用 File.list() 或 File.listFiles()(传统方式,慎用)
适用于简单场景或需兼容 Java 7 及更早版本,但有明显局限:
-
list()只返回文件名字符串数组,不带路径,无法直接操作; -
listFiles()返回File[],但遇到权限问题会返回null(不是空数组),容易引发 NPE; - 不支持流式处理,递归需手动写方法,易栈溢出或逻辑出错;
- 不区分符号链接,可能造成无限循环(除非显式检查)。
注意事项与最佳实践
- 路径建议用
Paths.get("...")创建Path,比new File("...")更符合现代 API 设计; - 遍历时若需处理大量文件,避免在
forEach中做耗时操作(如 IO 写入),可收集后批量处理; - 对不可达路径(如网络断开的 UNC 路径),
walk()默认抛IOException,可用onError回调忽略或记录:
Files.walk(Paths.get("\\server\share"),
FileVisitOption.FOLLOW_LINKS)
.onError(e -> System.err.println("跳过: " + e))
.filter(Files::isRegularFile)
.forEach(System.out::println);
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











