Adr*_*ebs 6 java file path nio2
此代码搜索特定文件:
Stream<Path> findMyFile = Files.find(Paths.get("c:\\temp\\pathtest"), Integer.MAX_VALUE,(p, a) -> p.endsWith("test.txt") && a.isRegularFile());
Stream<Path> findMyFileSecond = Files.walk(Paths.get("c:\\temp\\pathtest"),Integer.MAX_VALUE).filter(p -> p.endsWith("test.txt"));
findMyFile.forEach(System.out::println);
findMyFileSecond.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
两个结果都包含相同的文件,两种方法几乎同时完成.JavaDoc说如下:
此方法以完全按*walkwalk方法指定的方式遍历文件树.比较调用*java.util.stream.Stream #filter过滤器对@ {walk walk}方法返回的Stream*,此方法可能是通过*避免重复检索BasicFileAttributes来提高效率
什么时候应该和什么时候walk结合使用?什么是最佳做法?filterfind
TL;DR:如果您需要按属性过滤文件/目录 - 使用Files.find(),如果您不需要按文件属性过滤 - 使用Files.walk().
细节
文档中实际解释了细微差别,但在某种程度上感觉完全错误。阅读源代码很清楚:
文件查找:
return StreamSupport.stream(...)
.onClose(iterator::close)
.filter(entry -> matcher.test(entry.file(), entry.attributes()))
.map(entry -> entry.file());
Run Code Online (Sandbox Code Playgroud)文件.walk:
return StreamSupport.stream(...)
.onClose(iterator::close)
.map(entry -> entry.file());
Run Code Online (Sandbox Code Playgroud)这意味着,如果在您的最终过滤器中,您需要获取和验证文件属性 - 可能File.find会更快。那是因为 with File.walk,您的过滤器回调将需要额外调用 eg Files.readAttributes(file, BasicFileAttributes.class),而 with File.find- 属性已在过滤器回调中检索并提供给您。
我刚刚通过仅搜索文件(即排除文件夹)在 Windows 上使用我的示例 10K-files-in-many-folders 结构对其进行了测试:
// pre-Java7/8 way via recursive listFiles (8037 files returned): 1521.657 msec.
for (File f : new File(dir).listFiles()) {
if (f.isDirectory()) {
_getFiles(files, path, pattern);
} else {
...
}
}
// Files.walk(8037 files returned): 1575.766823 msec.
try (Stream<Path> stream = Files.walk(path, Integer.MAX_VALUE) {
files = stream.filter(p -> {
if (Files.isDirectory(p)) { return false; } // this extra check makes it much slower than Files.find
...
}).map(p -> p.toString()).collect(Collectors.toList());
}
// Files.find(8037 files returned): 27.606675 msec.
try (Stream<Path> stream = Files.find(path, Integer.MAX_VALUE, (p, a) -> !a.isDirectory())) {
files = stream.filter(p -> { ... }).map(p -> p.toString()).collect(Collectors.toList());
}
// Files.walkFileTree(8037 returned): 27.443974 msec.
Files.walkFileTree(new File(path).toPath(), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path p, BasicFileAttributes attrs) throws IOException {
...
return FileVisitResult.CONTINUE;
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1712 次 |
| 最近记录: |