准备工作:
准备的文件夹:431G,65919个文件
因为网上基本都在讲nio在网络上的应用,所以好奇nio对于本地效率,不过速度也跟filesystem有关,暂时只做windows上的测试。
遍历时间对比
walkFileTree 与 listFile 耗时对比:
代码:
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class App {
public static void main(String[] args) throws Exception {
Path path = Paths.get("E:\\书籍");
// PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:**-*");
// ArrayList<File> files = new ArrayList<>();
// 1.walkFileTree
long start1 = System.currentTimeMillis();
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
// if(pathMatcher.matches(file))
// files.add(file.toFile());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
// System.out.println(dir.getFileName());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException e) {
return FileVisitResult.CONTINUE;
}
});
long end1 = System.currentTimeMillis();
// 2.newDirectoryStream
long start2 = System.currentTimeMillis();
search(path.toFile());
long end2 = System.currentTimeMillis();
// 3.listFiles
long start3 = System.currentTimeMillis();
getFileNames(path);
long end3 = System.currentTimeMillis();
System.out.println("\r执行耗时:" + (end1 - start1));
System.out.println("\r执行耗时:" + (end2 - start2));
System.out.println("\r执行耗时:" + (end3 - start3));
}
private static void getFileNames(Path dir) {
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path path : stream) {
if(Files.isDirectory(path)) {
getFileNames(path);
}
}
} catch(IOException e) {
e.printStackTrace();
}
}
public static void search(File file) {
Queue<File> q = new LinkedList<>();
q.offer(file);
while (!q.isEmpty()) {
try {
for (File childfile : q.poll().listFiles()) {
// System.out.println(childfile.getName());
if (childfile.isDirectory()) {
q.offer(childfile);
}
}
} catch (Exception e) {
}
}
}
}
结果:
walkFileTree | listFiles | newDirectoryStream |
---|---|---|
68 | 451 | 493 |
64 | 464 | 482 |
61 | 478 | 457 |
67 | 477 | 488 |
59 | 474 | 466 |
遍历速度walkFileTree对比listFiles、newDirectoryStream差不多为7:1
已知的性能问题:isDirectory会进行一次和文件系统进行一次交互,当数量集很大的时候,造成的性能问题就不可忽视了。