7.4 文件系统的搜索
问题
用户希望查找文件树中满足给定属性的文件。
方案
使用 java.nio.file.Files 类定义的静态方法 find。
讨论
find 方法的签名如下:
- public static Stream<Path> find(Path start,
- int maxDepth,
- BiPredicate<Path, BasicFileAttributes> matcher,
- FileVisitOption... options)
- throws IOException
可以看到,find 方法的签名与 walk 方法类似,但增加了一个用于决定是否应返回特定 Path 的匹配器 BiPredicate。find 方法从给定路径开始执行深度优先搜索(depth-first search),直至达到 maxDepth 指定的目录级别。对于每条路径,find 方法都会调用 BiPredicate 进行评估。如果指定为 FileVisitOption 枚举的值,则执行后面的链接。
BiPredicate 需要根据每个路径元素及其关联的 BasicFileAttributes 对象返回布尔值。如例 7-8 所示,程序将返回 fileio 包(参见本书配套源代码)中所有非目录文件的路径。
例 7-8 查找
fileio包中的非目录文件
- try (Stream<Path> paths =
- Files.find(Paths.get("src/main/java"), Integer.MAX_VALUE,
- (path, attributes) ->
- !attributes.isDirectory() && path.toString().contains("fileio"))) {
- paths.forEach(System.out::println);
- } catch (IOException e) {
- e.printStackTrace();
- }
输出结果如下:
src/main/java/fileio/FileList.javasrc/main/java/fileio/ProcessDictionary.javasrc/main/java/fileio/SearchForFiles.javasrc/main/java/fileio/WalkTheTree.java
对于遍历文件树时遇到的每一个文件,find 方法都会根据给定的 BiPredicate 进行评估,类似于在 walk 方法返回的 Stream 上调用筛选器。不过,Javadoc 认为 find 方法避免了对 BasicFileAttributes 对象的冗余检索,因而能提高程序的效率。
类似地,由于返回的 Stream 封装了 DirectoryStream,在关闭流的同时,底层数据源也随之关闭。有鉴于此,在 try-with-resources 代码块中使用 find 方法是首选方案。
另见
有关文件系统的遍历请参见范例 7.3。
