列出目录的内容
列出目录的内容
您可以使用 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
,其原因是 IOException
。 Iterator
方法不能抛出异常。
使用通配符过滤目录列表
如果您只想获取名称与特定模式匹配的文件和子目录,可以使用 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 日