379. Java IO API - 启动文件树遍历
前面我们已经学习了如何通过 FileVisitor 或 SimpleFileVisitor 定义遍历逻辑。接下来,我们要回答一个关键问题:
💡 “如何启动这个文件树遍历过程?”
Java NIO 提供了两个重载的 Files.walkFileTree() 方法,分别适用于不同的场景需求。
✅ 方法一:最简启动方式
Files.walkFileTree(Path startingDir, FileVisitor<? super Path> visitor)
这个方法只需要两个参数:
startingDir:文件树的起点路径(Path对象)visitor:实现了FileVisitor的类实例
📌 适合快速、默认配置的遍历操作。
示例:启动一个打印文件的遍历器
Path startingDir = Paths.get("src");
PrintFiles pf = new PrintFiles(); // 继承自 SimpleFileVisitor
Files.walkFileTree(startingDir, pf);
⚙️ 方法二:高级可配置方式
Files.walkFileTree(
Path start,
Set<FileVisitOption> options,
int maxDepth,
FileVisitor<? super Path> visitor
)
这个版本提供了更多的控制能力:
| 参数 | 说明 |
|---|---|
start | 遍历起点 |
options | 遍历行为选项(如是否跟随符号链接) |
maxDepth | 最大遍历深度(如 3 表示“当前目录+2级子目录”) |
visitor | 处理逻辑的实现类 |
📌 适合需要更精细控制遍历范围和行为的场景。
🎯 可用选项:FileVisitOption
目前只有一个有效枚举项:
FileVisitOption.FOLLOW_LINKS—— 表示遍历中应跟随符号链接
👉 需要使用 EnumSet 来传递这个参数,例如:
EnumSet<FileVisitOption> opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
📦 示例:查找特定模式的文件,遍历所有层级
以下示例中,我们使用一个自定义的 Finder 文件访问器,并启用跟随符号链接的选项,遍历整个目录树:
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.EnumSet;
import static java.nio.file.FileVisitOption.*;
import static java.nio.file.FileVisitResult.*;
public class Finder extends SimpleFileVisitor<Path> {
private final PathMatcher matcher;
Finder(String pattern) {
matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (matcher.matches(file.getFileName())) {
System.out.println("🔍 Matched: " + file);
}
return CONTINUE;
}
}
public class FinderMain {
public static void main(String[] args) throws IOException {
Path startingDir = Paths.get("your/start/path");
String pattern = "*.java";
Finder finder = new Finder(pattern);
EnumSet<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);
Files.walkFileTree(startingDir, opts, Integer.MAX_VALUE, finder);
}
}
📌 上例中:
glob:*.java匹配所有.java文件- 遍历深度为
Integer.MAX_VALUE,表示“没有限制,直到遍历完所有目录”
💡 训练建议:如何设计练习?
- 给定一个目录,写一个
FileVisitor,打印所有.class文件 - 修改
maxDepth值,观察遍历结果的变化 - 结合
FOLLOW_LINKS处理符号链接中的循环引用(避免死循环) - 扩展访问器逻辑,查找超过 1MB 的大文件并统计总大小