如何在JDK7中使用目录通配符?

20
我一直在尝试使用JDK7中的新通配符功能,从文档和示例开始。
我可以使用像"glob:*.dat"这样的通配符。
Files.walkFileTree(startingDir, finder);

例如,但我一直无法使用"**"语法。我希望能够创建类似于:

matcher = FileSystems.getDefault().getPathMatcher("glob:" + "foo/**/bar/*.dat");

我希望您能给出一个简单的例子。这涉及到编程,并且与Windows 7有关。

更新: @Oleg 和 @JBNizet 澄清了“/”语法是与操作系统无关的。请注意,Javadocs 表明也可能存在着与操作系统相关的语法(?必须)

仍然存在问题: 已经采纳了 @Nizet 的建议并进行了编辑:

@Test
public void testStackoverflowGlobber() throws IOException {
    final PathMatcher matcher =
 FileSystems.getDefault().getPathMatcher("glob:*.cml");
        Files.walkFileTree(Paths.get("d:/petermr-workspace/jumbo-converters/jumbo-converters-cli/src/test/resources"), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println("try>> "+file);
                if (matcher.matches(file)) {
                    System.out.println("MATCHES>>"+file);
                }
                return FileVisitResult.CONTINUE;
            }
        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
            return FileVisitResult.CONTINUE;
        }
    });
}

这将会输出类似于:

try>> d:\petermr-workspace\jumbo-converters\jumbo-converters-cli\src\test\resources\examples\cdx\r19.cdx
try>> d:\petermr-workspace\jumbo-converters\jumbo-converters-cli\src\test\resources\examples\cdx\r19.cdxml
try>> d:\petermr-workspace\jumbo-converters\jumbo-converters-cli\src\test\resources\examples\cdx\r19.cml
try>> d:\petermr-workspace\jumbo-converters\jumbo-converters-cli\src\test\resources\examples\cdx\r19.ref.cdxml
try>> d:\petermr-workspace\jumbo-converters\jumbo-converters-cli\src\test\resources\examples\cdx\r19.ref.cml
try>> d:\petermr-workspace\jumbo-converters\jumbo-converters-cli\src\test\resources\examples\cif\aa2004.cml

但没有匹配的证据


1
如果您关心的是在任何Windows系统上都能正常工作,那么“/”将可以很好地解决这个问题。 - Oleg Mikheev
@Oleg 谢谢。所以我逻辑有些错误或者假设方法有不同的功能。因此,File.separator是错误的吗?[我发现官方文档相当简略] - peter.murray.rust
你尝试过 "glob:**/*.cml" 吗? - Kristof Neirynck
@Kristof 谢谢 - 看起来你必须使用 ** 组件。 - peter.murray.rust
2个回答

16

这里有一个可行的示例,可以显示d:/下任何子目录中的所有zip文件:

public static void main(String[] args) throws IOException {
    final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:d:/**/*.zip");
    Files.walkFileTree(Paths.get("d:/"), new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            if (matcher.matches(file)) {
                System.out.println(file);
            }
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
            return FileVisitResult.CONTINUE;
        }
    });
}

正如你所看到的,使用斜杠在Windows上也可以工作。


1
谢谢。它会检查相对文件路径吗? - peter.murray.rust
我已经接受这个答案,因为它解决了文件分隔符的问题。但是在我的环境中,我无法使其工作。Globbing语法似乎并没有得到很好的记录,也没有明确的例子。嗯,可能明天会起作用... - peter.murray.rust
1
如果你想删除特定驱动器(盘符)下的所有压缩文件,可以使用以下命令:glob:*/**/*.zip - Akhil Jain
1
驱动器特定部分可以使用模式 glob:**/*.zip 删除,甚至可以使用扩展名 glob:**/*.* - daniel.kahlenberg
1
这个可以运行,但不够高效。如果你的模式是 glob:/foo/bar/baz/**/*.zip,那么它会遍历整个文件树,而不仅仅是 /foo/bar/baz 组件。 - Jason S

7
你需要以 ** 开头启动你的全局变量。
matcher = FileSystems.getDefault().getPathMatcher("glob:**/foo/**/bar/*.dat");

否则,调用
matcher.matches(file)

尝试使用以相对路径 (/foo/) 开头的正则表达式来匹配文件的完整路径,而不是以绝对路径 (d:/petermr-workspace/.../foo) 开头。

在 glob 前加上 ** 只是告诉它忽略绝对路径的开头。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接