以下为多线程统计文件夹大小的工具类,经过测试,使用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
}