我希望使用 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/