379. Java IO API - 启动文件树遍历

0 阅读2分钟

379. Java IO API - 启动文件树遍历

前面我们已经学习了如何通过 FileVisitorSimpleFileVisitor 定义遍历逻辑。接下来,我们要回答一个关键问题:

💡 “如何启动这个文件树遍历过程?”

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 的大文件并统计总大小