Java8 NIO Stream>以递归方式检索目录大小的更有效方法?

时间:2016-11-18 03:22:38

标签: java recursion

对于给定目录,我尝试以递归方式检索每个目录的大小(以尽可能最有效的方式)。我希望尽可能使用Java8 NIO Streams(速度和效率),但是可以选择第三方库(为什么重新发明轮子)。

例如,在深度优先的情况下迭代目录会更有效,在我们向上移动每个级别时对子文件/ prev-calculated-directory大小求和。我目前的解决方案效率很低,因为它从顶层开始重新计算目录大小。

任何图书馆建议/代码样本/指导都将不胜感激......

当前解决方案:

import java.io.IOException;
import java.nio.file.*;
import java.util.Map;

import static java.util.stream.Collectors.toMap;

public class DirectorySizes {

    public static void main(String[] args) throws IOException {
        // retrieve map of path -> size...
        Map<Path, Long> directorySize = Files.walk(Paths.get("/tmp"))
                .filter(Files::isDirectory)
                .collect(toMap(Path::toAbsolutePath, DirectorySizes::getDirectorySize));
        // print {size} {directory}...
        directorySize.entrySet().forEach(e ->
                System.out.printf("%15s  %s %n", e.getValue(), e.getKey())
        );
    }

    public static long getDirectorySize(Path path) {
        try {
            return Files.walk(path).filter(Files::isRegularFile)
                    .mapToLong(DirectorySizes::getFileSize).sum();
        } catch (IOException e) {
            return 0;
        }
    }

    public static long getFileSize(Path file) {
        try {
            return Files.size(file);
        } catch (IOException e) {
            return 0;
        }
    }

}

示例输出:

       2812  C:\tmp\foobar\static\css 
       6936  C:\tmp\foobar\static 
       7821  C:\tmp\foobar

1 个答案:

答案 0 :(得分:1)

有一些可能会有所帮助的变化:

  • 您的FileVisitor传递BasicFileAttributes,其中包含文件的大小。您不需要使用Files.size重新计算它。
  • walkFileTree已经是深度优先。您应该能够在走树时收集尺寸信息进行整理