376. Java IO API - 使用 Globbing 和自定义 Filter 过滤目录内容
在实际开发中,我们经常需要列出特定类型的文件,比如所有 .java 文件、所有子目录,或者符合某个命名规则的文件。Java NIO 为我们提供了两种灵活的方式:
1️⃣ 使用 Globbing(通配符匹配)
🌟 示例:列出 .java、.class 和 .jar 文件
Path dir = Paths.get("your-directory-path-here");
try (DirectoryStream<Path> stream =
Files.newDirectoryStream(dir, "*.{java,class,jar}")) {
for (Path entry : stream) {
System.out.println("Matched file: " + entry.getFileName());
}
} catch (IOException e) {
System.err.println("Failed to read directory: " + e.getMessage());
}
✅ Glob 语法说明:
"*.java":匹配所有以.java结尾的文件"data-??.log":匹配如data-01.log、data-ab.log"*.{java,class,jar}":匹配多个后缀的文件,类似正则中的|逻辑
📘 Glob 是简单的模式匹配,不支持完整正则表达式。但足以应对常见的文件过滤需求。
2️⃣ 编写自定义 DirectoryStream.Filter
如果 glob 无法满足需求,比如:
- 只列出子目录
- 只列出大小大于
1MB的文件 - 忽略隐藏文件(以 "." 开头)
那你可以自定义一个过滤器!
🛠 示例:只保留目录条目的 Filter
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path path) throws IOException {
return Files.isDirectory(path);
}
};
🧪 使用自定义 Filter 遍历目录内容
Path dir = Paths.get("your-directory-path-here");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
for (Path entry : stream) {
System.out.println("Directory found: " + entry.getFileName());
}
} catch (IOException e) {
System.err.println("Error reading directory: " + e.getMessage());
}
🆚 Globbing 与 自定义 Filter 的对比
| 对比项 | Globbing | 自定义 Filter |
|---|---|---|
| 匹配方式 | 简单通配符(*.txt, data-??.log) | 完全自定义(任意逻辑) |
| 是否支持文件类型判断 | ❌ 不支持 | ✅ 支持(如 isDirectory) |
| 复杂匹配 | ❌ 较弱 | ✅ 可按文件大小、日期、权限等任意条件组合 |
| 适合场景 | 快速过滤后缀、命名 | 需要高级判断(如“所有非隐藏目录”) |
📣 小贴士:如何过滤整个文件树?
当前例子只作用于单层目录,如果你希望:
递归查找所有子目录(例如搜索整个工程目录下的所有
.java文件)
✅ 推荐使用 Java NIO 提供的 Files.walkFileTree(...) 方法配合 FileVisitor 实现,详见《遍历文件树》部分的内容。