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

我希望使用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在类似问题的评论中提到的,您可以使用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 fileStreams = new Vector(); 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 foundStreams, boolean includeHiddenFiles) { File[] fileList = dir.listFiles(); Arrays.sort(fileList, // Need in reproducible order new Comparator() { 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!"); } } } } 

我做了一个函数来计算目录上的MD5校验和:

首先,我使用的是FastMD5: http ://www.twmacinta.com/myjava/fast_md5.php

这是我的代码:

  def MD5HashDirectory(String fileDir) { MD5 md5 = new MD5(); new File(fileDir).eachFileRecurse{ file -> if (file.isFile()) { String hashFile = MD5.asHex(MD5.getHash(new File(file.path))); md5.Update(hashFile, null); } } String hashFolder = md5.asHex(); return hashFolder } 

HashCopy是一个Java应用程序。 它可以递归地生成和validation单个文件或目录上的MD5和SHA。 我不确定它是否有API。 它可以从www.jdxsoftware.org下载。

根据Stuart Rossiter的回答,但干净的代码和隐藏文件正确处理:

 import org.apache.commons.codec.digest.DigestUtils; import java.io.*; import java.nio.file.Files; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Vector; public class Hashing { public static String hashDirectory(String directoryPath, boolean includeHiddenFiles) throws IOException { File directory = new File(directoryPath); if (!directory.isDirectory()) { throw new IllegalArgumentException("Not a directory"); } Vector fileStreams = new Vector<>(); collectFiles(directory, fileStreams, includeHiddenFiles); try (SequenceInputStream sequenceInputStream = new SequenceInputStream(fileStreams.elements())) { return DigestUtils.md5Hex(sequenceInputStream); } } private static void collectFiles(File directory, List fileInputStreams, boolean includeHiddenFiles) throws IOException { File[] files = directory.listFiles(); if (files != null) { Arrays.sort(files, Comparator.comparing(File::getName)); for (File file : files) { if (includeHiddenFiles || !Files.isHidden(file.toPath())) { if (file.isDirectory()) { collectFiles(file, fileInputStreams, includeHiddenFiles); } else { fileInputStreams.add(new FileInputStream(file)); } } } } } } 

目前尚不清楚采用目录的md5sum意味着什么。 您可能需要文件列表的校验和; 您可能需要文件列表及其内容的校验和。 如果您已经自己对文件数据进行求和,我建议您为目录列表指定一个明确的表示(注意文件名中的恶意字符),然后每次计算和散列。 您还需要考虑如何处理特殊文件(unix世界中的套接字,管道,设备和符号链接; NTFS有文件流,我相信类似于符号链接的东西)。