首页 > 解决方案 > 优化:递归计算根文件夹下大量文件的MD5哈希

问题描述

我当前在根目录下生成所有文件的 MD5 哈希的方法,直到给定的深度如下所示。

截至目前,处理 appx 300 张图像大约需要 10 秒(旧的 intel core i3 cpu),每个图像平均大小为 5-10 MB。中的parallel选项stream没有帮助。无论有没有它,时间或多或少都保持不变。我怎样才能让它更快?

Files.walk(Path.of(rootDir), depth)
            .parallel() // doesn't help, time appx same as without parallel
            .filter(path -> !Files.isDirectory(path)) // skip directories
            .map(FileHash::getHash)
            .collect(Collectors.toList());

上面使用的getHash方法为流中正在处理的每个文件提供一个逗号分隔的hash,<full file path>输出行。

public static String getHash(Path path) {
    MessageDigest md5 = null;
    try {
      md5 = MessageDigest.getInstance("MD5");
      md5.update(Files.readAllBytes(path));
    } catch (Exception e) {
      e.printStackTrace();
    }
    byte[] digest = md5.digest();
    String hash = DatatypeConverter.printHexBinary(digest).toUpperCase();
    return String.format("%s,%s", hash, path.toAbsolutePath());
  }

标签: optimizationparallel-processingstreamchecksumjava-11

解决方案


返回的流Files.walk(Path.of(rootDir), depth)不能被有效地并行化(他没有大小,因此很难确定要并行化的切片)。在您提高性能的情况下,您需要首先收集Files.walk(...).

所以你必须这样做:

Files.walk(Path.of(rootDir), depth)
        .filter(path -> !Files.isDirectory(path)) // skip directories
        .collect(Collectors.toList())
        .stream()
        .parallel() // in my computer divide the time needed by 5 (8 core cpu and SSD disk)
        .map(FileHash::getHash)
        .collect(Collectors.toList());

推荐阅读