PathMatcher in NIO.2

In my last blog entry I show how to walk a file tree using a FileVisitor in a very simple Find example. Alan Bateman (the NIO.2 czar) suggested that, rather than use java.lang.String to match the file, I use the new PathMatcher API.

Good idea.

You can get the path matcher from the file system using this code:

PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
where pattern is, in this case, supplied at the command line.

At least two syntaxes are supported (others may be supported by a particular file system implementation): glob and regex. The getPathMatcher javadoc has more information.

Also note that the previous Find example only matched files, not directories. This is because visitFile is called once per file, but not for a directory: preVisitDirectory is used to take care of that omission.

To use this version of Find you might try:

java Find . "\*java"     Finds all files ending in "java".
java Find . "\*[0-9]\*"   Finds all files containing a numeric value.
java Find . "???"       Finds all files with exactly three letters or digits.

Here is the modified Find.java:

import java.io.\*;
import java.nio.file.\*;
import java.nio.file.attribute.\*;
import static java.nio.file.FileVisitResult.\*;
import java.io.IOException;
import java.util.\*;

/\*\*
 \* Sample code that finds files that match the specified glob pattern.
 \* For more information on what constitutes a glob pattern, see
 \* http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)
 \*/

public class Find {

    /\*\*
     \* A {@code FileVisitor} that finds all files that match the specified pattern.
     \*/
    public static class Finder implements FileVisitor {
        private final PathMatcher matcher;

        Finder(String pattern) {
            matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
        }

        void find(Path file) {
            if (matcher.matches(file.getName())) {
                System.out.format("%s%n", file);
            }
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
            find(file);
            return CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
            return CONTINUE;
        }

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

        @Override
        public FileVisitResult preVisitDirectory(Path dir) {
            find(dir);
            return CONTINUE;
        }

        @Override
        public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
            return CONTINUE;
        }
    }

    static void usage() {
        System.err.println("java Find path glob_pattern");
        System.exit(-1);
    }

    public static void main(String[] args) throws IOException {

        if (args.length < 2)
            usage();

        Path searchDir = Paths.get(args[0]);
        String pattern = args[1];

        // follow links when searching for files
        EnumSet<FileVisitOption> opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
        Finder finder = new Finder(pattern);
        Files.walkFileTree(searchDir, opts, Integer.MAX_VALUE, finder);
    }
}

-- Sharon Zakhour

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Blog about Java technology documentation and news about Java releases.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today