带有大小过滤器的Java8 Glob PathMatcher

时间:2016-02-09 13:39:38

标签: java

我的目标是创建一个具有globs功能的FileScanner,并添加一些自定义过滤功能(如min或max filesize)。

我的第一次尝试是:

    final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:**/*.java");
    Path path2 = Paths.get("c:/dummy");
    try (final Stream<Path> stream = Files.list(path2)) {
        stream.filter(pathMatcher::matches).forEach(FileProcessor::processFile);
    }

这样可以正常工作,以便在c:\ dummy目录中只找到* .java文件。但是我需要做什么才能找到小于1000字节的* .java文件?

我的尝试是:

    PathMatcher myMatcher = path -> {
        // Do size comparision ...
        return true;
    };

    Path path = Paths.get("c:/dummy");
    try (final Stream<Path> stream = Files.list(path)) {
        stream.filter(myMatcher::matches).forEach(FileProcessor::processFile);
    }

但是有了这个解决方案,我再也没有了。

最后一次尝试是:

Path path3 = Paths.get(&#34; c:/ dummy&#34;);         final PathMatcher pathMatcher2 = FileSystems.getDefault()。getPathMatcher(&#34; glob:** / * .java&#34;);

    Files.walkFileTree(path3, new SimpleFileVisitor<Path>() {

        @Override
        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
            if (pathMatcher2.matches(path)) {
                // Do size comparison
            }
            return FileVisitResult.CONTINUE;
        }

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

最后一个有效,但它看起来不太好,并且使用SimpleFileVisitor对象感觉有点复杂。

任何人都知道如何解决这个问题?

问候, Hauke

1 个答案:

答案 0 :(得分:1)

根据您要检查的文件名的属性,您可以改为使用Files.find()

// Note that you can use a `PathMatcher` for the name instead if you want
final BiPredicate<Path, BasicFileAttributes> filter =
    (path, attrs) -> path.getFileName().toString().endsWith(".java") && attrs.size() <= 1000L;

try (
    final Stream<Path> = Files.find(baseDir, Integer.MAX_VALUE, filter);
) {
    // process the stream
}

您也可以使用Files.walk();但是,Files.find()的优势在于它会自动为您检索属性:Files.walk()这必须手动完成。