7.2 以流的形式检索文件
问题
用户希望将目录中的所有文件作为 Stream 进行处理。
方案
使用 java.nio.file.Files 类定义的静态方法 list。
讨论
list 方法传入 Path 作为参数,并返回一个包装 DirectoryStream4 的 Stream。由于 DirectoryStream 接口继承自 AutoCloseable,try-with-resources 构造是使用 list 方法的最佳方式,如例 7-6 所示。
4这是一个 IO 流而非函数式流。
例 7-6
Files.list(path)方法的应用
- try (Stream<Path> list = Files.list(Paths.get("src/main/java"))) {
- list.forEach(System.out::println);
- } catch (IOException e) {
- e.printStackTrace();
- }
如果在具有标准 Maven 或 Gradle 结构的项目根目录下执行上述代码,程序将打印 src/ main/java 目录中所有文件和文件夹的名称。使用 try-with-resources 代码块,当 try 代码块执行完毕后,系统将在 Stream 上调用 close 方法,然后在底层 DirectoryStream 上调用 close 方法。请注意,目录和文件不是递归的。
执行本书配套的源代码(例 7-6),程序将输出目录和单个文件:
src/main/java/collectorssrc/main/java/concurrencysrc/main/java/datetime...src/main/java/Summarizing.javasrc/main/java/taskssrc/main/java/UseFilenameFilter.java
list 方法的签名如下,其返回类型为 Stream,参数为目录的路径:
- public static Stream<Path> list(Path dir) throws IOException
请注意,对非目录资源执行 list 方法将抛出 NotDirectoryException。
Javadoc 指出,list 方法返回的流具备弱一致性(weak consistency)。换言之,“流是线程安全的,但在迭代时不会冻结目录,因此它可能会(也可能不会)反映 list 方法返回后所发生的目录更新”。
另见
有关采用深度优先搜索遍历文件系统的讨论请参见范例 7.3。
