目的
计算制定目录下所有大小总和.
代码- 目录大小计算接口定义
public interface DirSizeCalc {
long getSize(final File file);
}
- 多线程计算方式 文件多时,执行优于递归
/**
* 采用ForkJoinPool多线程计算目录大小
*/
public class DirSizeCalcByForkJoinPool implements DirSizeCalc {
@Override
public long getSize(final File file) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
return forkJoinPool.invoke(new FileSizeFinder(file));
}
private static class FileSizeFinder extends RecursiveTask {
final File file;
FileSizeFinder(final File theFile) {
file = theFile;
}
@Override
public Long compute() {
long size = 0;
if (file.isFile()) {
size = file.length();
} else {
final File[] children = file.listFiles();
if (children != null) {
List tasks = new ArrayList();
for (final File child : children) {
if (child.isFile()) {
size += child.length();
} else {
tasks.add(new FileSizeFinder(child));
}
}
for (final ForkJoinTask task : invokeAll(tasks)) {
size += task.join();
}
}
}
return size;
}
}
}
- 递归计算方式
/**
* 采用递归调用计算目录大小
*/
public class DirSizeCalcByRecursion implements DirSizeCalc {
@Override
public long getSize(final File file) {
if (file.isFile())
return file.length();
final File[] children = file.listFiles();
long total = 0;
if (children != null)
for (final File child : children)
total += getSize(child);
return total;
}
}
- 调用方法:
public class Test {
public static void main(final String[] args) {
String dirPath = "/users/jerry/projects/tms/tms";
File file = new File(dirPath);
System.out.print("递归方式计算\t");
calcDirSize(file, new DirSizeCalcByRecursion());
System.out.print("多线程方式计算\t");
calcDirSize(file, new DirSizeCalcByForkJoinPool());
}
private static void calcDirSize(File file, DirSizeCalc dirSizeCalc) {
long start = System.nanoTime();
long total = dirSizeCalc.getSize(file);
long end = System.nanoTime();
System.out.println("目录大小: " + total+";耗时: " + (end - start) / 1.0e9);
}
}
- 执行结果样例:
递归方式计算 目录大小: 167502662;耗时: 0.233380609
多线程方式计算 目录大小: 167502662;耗时: 0.060410266