以下爲多線程統計文件夾大小的工具類,經過測試,使用forkjointask能更好的發揮多核心cpu的性能,提升速度。這裏使用List和for 循環代替了遞歸。
* 獲取文件夾大小
* @param dir
* @return
*/
public static long getDirSize(String dir) {
File folder = new File(dir);
if(!folder.isDirectory()) {
return folder.length();
}
return IoOperateHolder.forkjoinPool.invoke(new CalDirCommand(folder));
}
static class CalDirCommand extends RecursiveTask<Long> {
private File folder;
CalDirCommand(File folder){
this.folder = folder;
}
@Override
protected Long compute() {
AtomicLong size = new AtomicLong(0);
File[] files = folder.listFiles();
if(files == null || files.length == 0) {
return 0L;
}
List<ForkJoinTask<Long>> jobs = new ArrayList<>();
for(File f : files) {
if(!f.isDirectory()) {
size.addAndGet(f.length());
} else {
jobs.add(new CalDirCommand(f));
}
}
for(ForkJoinTask<Long> t : invokeAll(jobs)) {
size.addAndGet(t.join());
}
return size.get();
}
}
private static final class IoOperateHolder {
final static ForkJoinPool forkjoinPool = new ForkJoinPool();
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
long result = getDirSize("/Users/sunhf");
System.out.println("大小:"+result+"字節, 用時:"+(System.currentTimeMillis() - start)+"ms");
//單線程 大小:263251930518
}