我的目标是创建一个具有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
答案 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()
这必须手动完成。