How do I use directory globbing in JDK7
Asked Answered
W

2

20

I have been trying to use the new globbing feature in JDK7, starting from the documentation and examples

I can get globs such as "glob:*.dat" to work with the

Files.walkFileTree(startingDir, finder);

example but I have been unable to get the "**" syntax working. I would like to be able to create something like:

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

and would be grateful for a simple example. I am using Windows 7.

UPDATE: @Oleg and @JBNizet make it clear that the "/" syntax is OS-independent. Note that the Javadocs suggest that OS-dependent syntax is also possible (?required)

STILL PROBLEMS: Have taken @Nizet and edited as follows:

@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;
        }
    });
}

and this gives output such as:

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

but no evidence of matching

Woodnote answered 5/2, 2012 at 10:31 Comment(4)
/ will work fine on any Windows system if that's your concernCesena
@Oleg thanks. So I have got some logic wrong or assumed the methods have different functionality. is File.separator therefore wrong? [I find the official documentation rather sketchy]Woodnote
have you tried "glob:**/*.cml"?Clayson
@Kristof thanks - it seems that you have to use the ** componentWoodnote
V
16

Here's a working example which displays all the zip files in any descendant directory of d:/:

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;
        }
    });
}

As you see, using forward slashes works on Windows.

Vilma answered 5/2, 2012 at 11:36 Comment(5)
Thanks. Will it check relative file paths?Woodnote
have accepted this as it's the only answer and it tackled the problem of file separator. But I can't get it to work on my environment. The globbing syntax seems rather lightly documented and there aren't clear examples. Oh well, will probably work tomorrow...Woodnote
If you even want to remove the drive specific use following glob:*/**/*.zipGrabowski
the drive specific part can be removed with pattern glob:**/*.zip even the extension glob:**/*.*Roxie
Ummm.... this works, but it's not efficient. If your pattern is glob:/foo/bar/baz/**/*.zip then it will walk the entire file tree, not just the /foo/bar/baz component.Mccluskey
S
7

You need to start your glob with **

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

Otherwise, calling

matcher.matches(file)

attempts to match the full path to the file against a regular expression that starts with the relative path (/foo/), rather than with the absolute path (d:/petermr-workspace/.../foo).

Prepending the ** to the glob just tells it to ignore the beginning of the absolute path.

Sorensen answered 4/1, 2013 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.