Java 文件系统的遍历,用户希望对文件系统进行深度优先遍历(depth-first traversal),可以使用 java.nio.file.Files
类定义的静态方法 walk
。
Java 文件系统的遍历 问题描述
用户希望对文件系统进行深度优先遍历(depth-first traversal)。
Java 文件系统的遍历 解决方案
使用 java.nio.file.Files
类定义的静态方法 walk
。
Java 文件系统的遍历 具体实例
walk
方法的签名如下:
public static Stream<Path> walk(Path start,
FileVisitOption... options)
throws IOException
walk
方法的参数为起始 Path
以及 FileVisitOption
值的可变参数列表。从起始路径开始对文件系统执行深度优先遍历,返回一个由 Path
实例惰性填充的 Stream
。
由于返回的 Stream
封装了 DirectoryStream
,仍然建议在 try-with-resources
代码块中使用 walk
方法,如例 7-7 所示。
例 7-7 文件树的遍历
try (Stream<Path> paths = Files.walk(Paths.get("src/main/java"))) {
paths.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
walk
方法传入零个或多个 FileVisitOption
值作为第二个参数以及后续参数,不过本例并未使用任何 FileVisitOption
值。FileVisitOption
是 Java 1.7 引入的一种枚举类型,所包含的唯一枚举常量为 FOLLOW_LINKS
。至少从理论上说,FOLLOW_LINKS
意味着文件树中可能存在循环,因此流将跟踪所访问的文件。一旦检测到循环,程序将抛出 FileSystemLoopException
。
执行本书配套的源代码(例 7-7),输出类似于:
src/main/java
src/main/java/collectors
src/main/java/collectors/Actor.java
src/main/java/collectors/AddCollectionToMap.java
src/main/java/collectors/Book.java
src/main/java/collectors/CollectorsDemo.java
src/main/java/collectors/ImmutableCollections.java
src/main/java/collectors/Movie.java
src/main/java/collectors/MysteryMen.java
src/main/java/concurrency
src/main/java/concurrency/CommonPoolSize.java
src/main/java/concurrency/CompletableFutureDemos.java
src/main/java/concurrency/FutureDemo.java
src/main/java/concurrency/ParallelDemo.java
src/main/java/concurrency/SequentialToParallel.java
src/main/java/concurrency/Timer.java
src/main/java/datetime
...
程序采用惰性方式遍历路径,所生成的流必然包含至少一个元素(起始参数)。对于遇到的每条路径,程序将判断它是否为目录,是则遍历其中的所有条目,然后移动到下一个同级元素(sibling)。其结果是一种深度优先遍历。程序访问每个目录包含的所有条目之后,将关闭该目录。
walk
方法还包括以下重载形式:
public static Stream<Path> walk(Path start,
int maxDepth,
FileVisitOption... options)
throws IOException
其中,参数 maxDepth
是要访问的目录级别的最大值,0 表示只访问起始文件。如果不使用 maxDepth
,可以通过 Integer.MAX_VALUE
值来指定应访问所有级别。