java - 如何使用java或groovy计算目录上的md5校验和?

标签 java groovy directory md5 checksum

我希望使用 java 或 groovy 来获取完整目录的 md5 校验和。

我必须将源目录复制到目标,校验源和目标,然后删除源目录。

我找到了这个文件脚本,但是如何对目录执行同样的操作?

import java.security.MessageDigest

def generateMD5(final file) {
    MessageDigest digest = MessageDigest.getInstance("MD5")
    file.withInputStream(){ is ->
        byte[] buffer = new byte[8192]
        int read = 0
        while( (read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }
    }
    byte[] md5sum = digest.digest()
    BigInteger bigInt = new BigInteger(1, md5sum)

    return bigInt.toString(16).padLeft(32, '0')
}

有更好的方法吗?

最佳答案

我有同样的要求,并选择我的“目录哈希”作为目录中所有(非目录)文件的串联流的 MD5 哈希。正如 Crozin 在 a similar question 的评论中提到的那样,您可以使用 SequenceInputStream 充当连接其他流负载的流。我正在使用Apache Commons Codec MD5算法。

基本上,您可以递归访问目录树,将 FileInputStream 实例添加到非目录文件的 Vector 中。然后,Vector 可以方便地使用 elements() 方法来提供 SequenceInputStream 需要循环的Enumeration。对于 MD5 算法,这仅显示为一个 InputStream

一个问题是,您需要每次都以相同的顺序呈现文件,以便哈希值与相同的输入相同。 File 中的 listFiles() 方法不保证排序,因此我按文件名排序。

我正在为 SVN 控制的文件执行此操作,并且希望避免散列隐藏的 SVN 文件,因此我实现了一个标志来避免隐藏文件。

相关基本代码如下。 (显然它可以被“强化”。)

import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.util.*;

public String calcMD5HashForDir(File dirToHash, boolean includeHiddenFiles) {

    assert (dirToHash.isDirectory());
    Vector<FileInputStream> fileStreams = new Vector<FileInputStream>();

    System.out.println("Found files for hashing:");
    collectInputStreams(dirToHash, fileStreams, includeHiddenFiles);

    SequenceInputStream seqStream = 
            new SequenceInputStream(fileStreams.elements());

    try {
        String md5Hash = DigestUtils.md5Hex(seqStream);
        seqStream.close();
        return md5Hash;
    }
    catch (IOException e) {
        throw new RuntimeException("Error reading files to hash in "
                                   + dirToHash.getAbsolutePath(), e);
    }

}

private void collectInputStreams(File dir,
                                 List<FileInputStream> foundStreams,
                                 boolean includeHiddenFiles) {

    File[] fileList = dir.listFiles();        
    Arrays.sort(fileList,               // Need in reproducible order
                new Comparator<File>() {
                    public int compare(File f1, File f2) {                       
                        return f1.getName().compareTo(f2.getName());
                    }
                });

    for (File f : fileList) {
        if (!includeHiddenFiles && f.getName().startsWith(".")) {
            // Skip it
        }
        else if (f.isDirectory()) {
            collectInputStreams(f, foundStreams, includeHiddenFiles);
        }
        else {
            try {
                System.out.println("\t" + f.getAbsolutePath());
                foundStreams.add(new FileInputStream(f));
            }
            catch (FileNotFoundException e) {
                throw new AssertionError(e.getMessage()
                            + ": file should never not be found!");
            }
        }
    }

}

关于java - 如何使用java或groovy计算目录上的md5校验和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9169137/

相关文章:

java - 检查字符串数组是否按字典顺序排序,不区分大小写

java - 我的 OSGi-bundle 多次无意中启动和停止

Groovy 比较两个字符串

Python错误: Cannot find the file specified

html - 上传 Yeoman 创建的网站后网站不显示

java - 如何按参数值拆分Spring MVC请求映射

java - 无法更新 .jar 内的 manifest.mf : line too long error

grails - 来自 Mixin 的公共(public)域列的常见 beforeInsert 和 beforeUpdate 方法

java - 通过 Spock 测试应用参数约束

linux - 比较脚本帮助