Java递归遍历文件夹查文件推荐用Files.walk()(流式安全)或Files.find()(可控深度),次选File手动递归;需校验目录可读、避免空指针,匹配用equals()或toLowerCase().contains(),注意中文路径编码与符号链接循环。

Java 递归遍历文件夹查找指定文件,核心是用 File 或更推荐的 Files.walk() / Files.find()(Java 8+),配合递归逻辑或流式处理匹配文件名。
用 File 类手动递归(兼容老版本,逻辑清晰)
适用于 Java 7 及以上,需自己写递归方法,注意空指针和权限问题:
- 判断当前
File是否为目录,是则遍历其子文件/子目录;否则检查是否匹配目标文件名 - 递归调用前建议先校验
file.isDirectory()和file.canRead(),避免异常中断 - 匹配时建议用
String.equals()(精确匹配)或String.toLowerCase().contains()(模糊查找),注意大小写敏感性
示例代码片段:
public static void searchFile(File dir, String targetName) {
if (!dir.exists() || !dir.isDirectory() || !dir.canRead()) return;
File[] files = dir.listFiles();
if (files == null) return;
for (File file : files) {
if (file.isDirectory()) {
searchFile(file, targetName); // 递归进入子目录
} else if (targetName.equals(file.getName())) {
System.out.println("找到: " + file.getAbsolutePath());
}
}
}
// 调用:searchFile(new File("/path/to/root"), "config.txt");
用 Files.walk() 流式遍历(推荐,简洁安全)
Java 8 引入,自动处理符号链接、异常(可选跳过),支持函数式风格:
立即学习“Java免费学习笔记(深入)”;
-
Files.walk()返回Stream<Path>,可链式调用filter()+forEach() - 用
Files.isRegularFile()排除非文件项(如目录、设备文件) - 用
path.getFileName().toString().equals(...)匹配文件名,避免路径干扰 - 建议包裹在 try-with-resources 或 try-catch 中,捕获
IOException
示例:
try (Stream<Path> stream = Files.walk(Paths.get("/path/to/root"))) {
stream.filter(Files::isRegularFile)
.filter(path -> "log4j2.xml".equals(path.getFileName().toString()))
.forEach(path -> System.out.println("命中: " + path));
} catch (IOException e) {
e.printStackTrace();
}
用 Files.find() 精确控制深度和条件(适合限定范围)
当只需查固定层级(如只查两层子目录),比 walk() 更高效:
-
Files.find(root, maxDepth, predicate)第三个参数是BiPredicate<Path, BasicFileAttributes> - 可在 predicate 中同时判断是否为文件、文件名是否匹配、最后修改时间等多条件
- 同样支持 try-with-resources,且默认跳过无法访问的路径(不抛异常)
示例(查 3 层内所有 .jar 文件):
try (Stream<Path> stream = Files.find(
Paths.get("/lib"),
3,
(path, attrs) -> attrs.isRegularFile() &&
path.toString().endsWith(".jar"))) {
stream.forEach(System.out::println);
}
注意事项与避坑点
实际使用中容易忽略但关键的细节:
-
中文路径或特殊字符:确保 JVM 启动参数含
-Dfile.encoding=UTF-8,避免listFiles()返回 null -
大目录性能:递归太深可能栈溢出,
Files.walk()内部用迭代实现,更稳定;必要时加超时或线程中断机制 -
软链接循环:
Files.walk()默认会检测并跳过循环符号链接;手动递归需自行记录已访问路径 Set 防重入 -
权限拒绝:某些系统目录(如 /proc、/sys)可能拒绝读取,
Files.walk()默认静默跳过,而File.listFiles()返回 null,需判空处理


















