测试对比File类递归与SimpleFileVisitor类遍历文件夹的耗时:
package other;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FilterMp3 {
private List<File> musicList = new ArrayList<>();
private List<File> musicList2 = new ArrayList<>();
private long fLen = 1024*1024*3;
private String filterD = "D:/";
//遍历方法1:
public List<File> getLocalMp3(){
File[] rootDirectory = new File(filterD).listFiles();
long start = System.currentTimeMillis();
System.out.println("开始递归" + start);
nextDirectory(rootDirectory);
long end = System.currentTimeMillis();
System.out.println("结束递归"+ end);
System.out.println("mp3集合长度:"+musicList.size() + " 耗时:" + (end - start) + "ms");
return musicList;
}
private void nextDirectory(File[] directory){
// System.out.println("directory:"+ Arrays.toString(directory));
for(File f : directory){
// System.out.println(f.getName());
if(f.isDirectory() && !f.isHidden() && !f.getName().startsWith(".")){
File[] child = f.listFiles();
nextDirectory(child);
}else if(f.getName().endsWith(".mp3") && f.length()>fLen){
musicList.add(f);
}
}
}
//遍历方法2:
private List<File> getMp3FromeFileVisitor() throws IOException{
long start2 = System.currentTimeMillis();
Files.walkFileTree(Paths.get(filterD), new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file,BasicFileAttributes attrs){
if(file.getFileName().toString().endsWith(".mp3") && attrs.size()>fLen){
musicList2.add(file.toFile());
// System.out.println("文件:"+file.toFile().getName());
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,BasicFileAttributes attrs){
// System.out.println("方法2访问文件夹:" + dir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file,IOException e){
return FileVisitResult.CONTINUE;
}
});
long end2 = System.currentTimeMillis();
System.out.println("方法2结果:" + musicList2.size()+" " + "用时:" +(end2 - start2) +"ms");
return musicList2;
}
public static void main(String[] args) {
FilterMp3 fm = new FilterMp3();
fm.getLocalMp3();
try {
fm.getMp3FromeFileVisitor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:SimpleFileVisitor遍历比File遍历快将近50%
开始递归1513145408629
结束递归1513145416589
mp3集合长度:196 耗时:7960ms
方法2结果:196 用时:4157ms
使用SimpleFileVisitor时每次读到.dll文件时就会报错提示“System information……”,在visitFileFailed()中使用return FileVisiResult.CONTINUE之后正常。
之所以SimpleFileVisitor比File快,可能就是SimpleFileVisitor忽略了系统文件吧?