PathMatcher 是 Java NIO.2 提供的轻量级路径匹配工具,支持 glob 和 regex 两种模式,基于 FileSystem 创建、线程安全;glob 语法简洁常用(如 */.java),regex 更灵活但需注意转义与路径分隔符处理。

Java 中的 PathMatcher 是 NIO.2 提供的轻量级路径匹配工具,适合做文件/目录路径的规则判断(比如过滤日志、扫描资源、忽略某些路径),它不支持正则表达式,而是基于简洁的 glob 或 regex 语法,由 FileSystem 创建,线程安全,开销小。
一、PathMatcher 的两种模式:glob 和 regex
glob 是最常用的方式,语法简单直观,适合大多数路径匹配场景;regex 更强大但需注意转义和路径分隔符处理(如 Windows 的 \ 需双写或用正斜杠)。
- glob 示例:
**/*.java匹配任意层级下的所有 Java 文件;config/*.properties匹配 config 目录下一级的 properties 文件 - regex 示例:
regex:^.*\\.xml$(注意开头的regex:前缀);Windows 路径建议统一用/或Pattern.quote()处理分隔符 - 创建方式:
FileSystems.getDefault().getPathMatcher("glob:**/*.log")
二、glob 通配符规则详解
glob 不是正则,它的符号含义固定且有限:
-
*:匹配当前目录下任意**不含**路径分隔符的文件名(如*.txt→a.txt,但不匹配sub/a.txt) -
**:匹配**跨目录层级**的任意路径(如**/*.md→README.md、docs/api.md、src/test/notes.md) -
?:匹配任意单个字符(不含分隔符,如?.log→a.log,但不匹配ab.log) -
[abc]或[a-z]:匹配方括号内任一字符(类似正则字符类) - 字面量字符(包括
.、-等)直接匹配,无需转义(.java就是匹配字面量点+java)
三、实际使用示例:遍历并过滤文件
结合 Files.walk() 和 PathMatcher 可高效筛选路径:
立即学习“Java免费学习笔记(深入)”;
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**/{*.java,*.xml}");
try (Stream stream = Files.walk(Paths.get("src"))) {
stream.filter(matcher::matches)
.forEach(System.out::println);
}
- 注意:
{a,b}是 glob 的“组匹配”扩展(JDK 7+ 支持),表示“a 或 b”,不是所有 FileSystem 都支持,推荐优先用多个 matcher 或逻辑 or - 路径传入
matcher.matches(path)时,path应为相对路径或与 pattern 语义一致(例如 pattern 是**/*.log,传入Paths.get("a/b/c.log")没问题;若 pattern 是logs/*.log,就应确保 path 是相对于logs的,或改用绝对路径 + 更宽泛 pattern) - 大小写敏感性取决于底层文件系统(Linux 默认敏感,Windows 默认不敏感),如需强制不敏感,可用
regex:(?i).*\.java
四、常见坑与注意事项
用错 pattern 或忽略环境细节容易导致匹配失败:
-
**必须单独成段(如foo/**/bar合法,foo**bar非法) - Windows 路径中反斜杠
\在字符串里要写成\\,但更稳妥的是全部用正斜杠/(NIO 接口内部自动适配) -
PathMatcher不解析符号链接,匹配的是路径字符串本身,不是真实文件属性 - 如果 pattern 以
/开头(如/home/**/*.txt),它会尝试匹配绝对路径;一般建议 pattern 不带根,靠输入 path 控制范围
基本上就这些。PathMatcher 不复杂但容易忽略语义边界,用好 glob 规则比硬套正则更稳更快。










