系列中的上一篇
当前教程
列出目录的内容
系列中的下一篇

系列中的上一篇: 创建和读取目录

系列中的下一篇: 遍历文件树

列出目录的内容

 

列出目录的内容

您可以使用 newDirectoryStream(Path) 方法列出目录的所有内容。此方法返回一个实现 DirectoryStream 接口的对象。实现 DirectoryStream 接口的类也实现了 Iterable,因此您可以遍历目录流,读取所有对象。这种方法可以很好地扩展到非常大的目录。

请记住: 返回的 DirectoryStream 是一个流。如果您没有使用 try-with-resources 语句,请不要忘记在 finally 块中关闭流。try-with-resources 语句会为您处理此操作。您可以在 流部分 中了解更多关于流的信息。

以下代码片段展示了如何打印目录的内容

Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
    for (Path file: stream) {
        System.out.println(file.getFileName());
    }
} catch (IOException | DirectoryIteratorException x) {
    // IOException can never be thrown by the iteration.
    // In this snippet, it can only be thrown by newDirectoryStream.
    System.err.println(x);
}

迭代器返回的 Path 对象是相对于目录解析的条目名称。因此,如果您列出 /tmp 目录的内容,则条目将以 /tmp/a/tmp/b 等形式返回。

此方法返回目录的全部内容: 文件、链接、子目录和隐藏文件。如果您想更具选择性地检索内容,可以使用其他 newDirectoryStream() 方法,如本页后面所述。

请注意,如果在目录迭代期间发生异常,则会抛出 DirectoryIteratorException,其原因是 IOExceptionIterator 方法不能抛出异常。

 

使用通配符过滤目录列表

如果您只想获取名称与特定模式匹配的文件和子目录,可以使用 newDirectoryStream(Path, String) 方法,该方法提供了一个内置的通配符过滤器。如果您不熟悉通配符语法,请参阅本页末尾的 什么是通配符 部分。

例如,以下代码片段列出了与 Java 相关的文件: .class.java.jar 文件。

Path dir = ...;
try (DirectoryStream<Path> stream =
     Files.newDirectoryStream(dir, "*.{java,class,jar}")) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    // IOException can never be thrown by the iteration.
    // In this snippet, it can // only be thrown by newDirectoryStream.
    System.err.println(x);
}

 

编写您自己的目录过滤器

也许您想根据与模式匹配以外的某些条件来过滤目录的内容。您可以通过实现 DirectoryStream.Filter 接口来创建自己的过滤器。此接口包含一个方法,accept(),它确定文件是否满足搜索要求。

例如,以下代码片段实现了一个仅检索目录的过滤器

DirectoryStream.Filter<Path> filter =
    newDirectoryStream.Filter<Path>() {
    public boolean accept(Path file) throws IOException {
        try {
            return (Files.isDirectory(path));
        } catch (IOException x) {
            // Failed to determine if it's a directory.
            System.err.println(x);
            return false;
        }
    }
};

创建过滤器后,可以使用 newDirectoryStream(Path, DirectoryStream.Filter) 方法调用它。以下代码片段使用 isDirectory() 过滤器仅将目录的子目录打印到标准输出

Path dir = ...;
try (DirectoryStream<Path>
                       stream = Files.newDirectoryStream(dir, filter)) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    System.err.println(x);
}

此方法用于仅过滤单个目录。但是,如果您想查找文件树中的所有子目录,可以使用 遍历文件树 的机制。

 

什么是通配符

您可以使用通配符语法来指定模式匹配行为。

通配符模式指定为字符串,并与其他字符串(如目录或文件名)匹配。通配符语法遵循几个简单的规则

  • 星号 * 匹配任意数量的字符(包括无字符)。
  • 两个星号 ** 的作用与 * 相同,但会跨越目录边界。此语法通常用于匹配完整路径。
  • 问号 ? 匹配正好一个字符。
  • 大括号指定子模式的集合。例如
    • {sun,moon,stars} 匹配 "sun"、"moon" 或 "stars"。
    • {temp*,tmp*} 匹配所有以 "temp" 或 "tmp" 开头的字符串。
  • 方括号表示一组单个字符,或者当使用连字符 (-) 时,表示一个字符范围。例如
    • [aeiou] 匹配任何小写元音。
    • [0-9] 匹配任何数字。
    • [A-Z] 匹配任何大写字母。
    • [a-z,A-Z] 匹配任何大写或小写字母。在方括号内,*?\ 匹配自身。
  • 所有其他字符匹配自身。
  • 要匹配 *、? 或其他特殊字符,可以使用反斜杠字符进行转义。例如: \ 匹配单个反斜杠,? 匹配问号。

以下是一些通配符语法的示例

  • *.html – 匹配所有以 .html 结尾的字符串
  • ??? – 匹配所有具有正好三个字母或数字的字符串
  • *[0-9]* – 匹配所有包含数字值的字符串
  • *.{htm,html,pdf} – 匹配任何以 .htm、.html 或 .pdf 结尾的字符串
  • a?*.java – 匹配任何以 a 开头、后面至少有一个字母或数字、以 .java 结尾的字符串
  • {foo*,*[0-9]*} – 匹配任何以 foo 开头的字符串或任何包含数字值的字符串

注意: 如果您在键盘上键入通配符模式,并且它包含其中一个特殊字符,则必须将模式放在引号中 ("*"),使用反斜杠 (\*),或者使用命令行支持的任何转义机制。

通配符语法功能强大且易于使用。但是,如果它不能满足您的需求,您也可以使用正则表达式。有关更多信息,请参阅有关正则表达式的部分。

有关通配符语法的更多信息,请参阅 getPathMatcher(String) 方法在 FileSystem 类中的 API 规范。


上次更新: 2023 年 1 月 25 日


系列中的上一篇
当前教程
列出目录的内容
系列中的下一篇

系列中的上一篇: 创建和读取目录

系列中的下一篇: 遍历文件树