推荐使用 Files.walk()(Java 8+),它简洁安全、支持流式处理,自动处理符号链接和权限异常;可限制深度、结合 filter 精准筛选文件或目录,也可用 Files.find() 按属性条件过滤,复杂逻辑则选用 Files.walkFileTree 配合 SimpleFileVisitor。

Java 中遍历指定目录下的所有文件和子目录,推荐使用 Files.walk()(Java 8+),它简洁、安全、支持流式处理,且自动处理符号链接和权限异常。
用 Files.walk() 递归遍历(最常用)
这是现代 Java 最推荐的方式,基于 NIO.2,一行代码就能获取所有路径:
- 调用
Files.walk(Paths.get("your/dir"))返回一个Stream<path></path> - 可链式调用
filter()、forEach()或collect()处理结果 - 默认包含起始目录本身;如只需文件,加
.filter(Files::isRegularFile) - 如需排除子目录,加
.filter(Files::isRegularFile);如需只列目录,用.filter(Files::isDirectory)
示例:
try (Stream<Path> paths = Files.walk(Paths.get("src/main/resources"))) {
paths.filter(Files::isRegularFile)
.forEach(System.out::println);
}用 Files.walk() 限制深度(避免过深遍历)
防止意外进入海量嵌套目录(如 node_modules 或 .git):
立即学习“Java免费学习笔记(深入)”;
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
- 传入第二个参数指定最大深度,例如
Files.walk(path, 3)表示最多深入 3 层子目录 - 深度从 0 开始计:根目录为 0,其直接子目录为 1,依此类推
- 配合
filter可精准控制范围,比如只处理二级以内的 .java 文件
用 Files.find() 做条件过滤遍历
如果需要按属性(如修改时间、大小、文件名模式)筛选,Files.find() 更合适:
- 签名:
Files.find(root, maxDepth, biPredicate) -
biPredicate接收Path和BasicFileAttributes,可判断是否匹配 - 例如:查找 7 天内修改的所有 .log 文件
示例:
long oneWeekAgo = System.currentTimeMillis() - 7L * 24 * 3600 * 1000;
Files.find(Paths.get("logs"), 5,
(path, attrs) -> path.toString().endsWith(".log") &&
attrs.lastModifiedTime().toMillis() > oneWeekAgo)
.forEach(System.out::println);传统方式:Files.walkFileTree(适合复杂逻辑)
当需要在遍历中做精细控制(如跳过某些目录、捕获异常、统计信息),用 SimpleFileVisitor:
- 重写
visitFile()处理文件,preVisitDirectory()处理目录进入前逻辑 - 返回
FileVisitResult.CONTINUE继续,SKIP_SUBTREE跳过当前目录下所有内容 - 异常由
visitFileFailed()捕获,不会中断整个遍历
示例:跳过名为 target 的目录
Files.walkFileTree(Paths.get("project"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (dir.getFileName().toString().equals("target")) {
return FileVisitResult.SKIP_SUBTREE;
}
return FileVisitResult.CONTINUE;
}
<pre class="brush:php;toolbar:false;">@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println("文件: " + file);
return FileVisitResult.CONTINUE;
}});

















