Java 获取文件哈希性能/优化
我正在尽可能快地获取文件的哈希值。我有一个程序,它可以散列由随机文件大小(每个文件大小从几KB到5GB+不等)组成的大型数据集(100GB+),这些数据集可以跨越少数文件到数十万个文件之间的任意位置 程序必须支持所有Java支持的算法(MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512) 目前我使用:Java 获取文件哈希性能/优化,java,algorithm,file,hash,Java,Algorithm,File,Hash,我正在尽可能快地获取文件的哈希值。我有一个程序,它可以散列由随机文件大小(每个文件大小从几KB到5GB+不等)组成的大型数据集(100GB+),这些数据集可以跨越少数文件到数十万个文件之间的任意位置 程序必须支持所有Java支持的算法(MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512) 目前我使用: /** * Gets Hash of file. * * @param file String path + filename of file to get has
/**
* Gets Hash of file.
*
* @param file String path + filename of file to get hash.
* @param hashAlgo Hash algorithm to use. <br/>
* Supported algorithms are: <br/>
* MD2, MD5 <br/>
* SHA-1 <br/>
* SHA-256, SHA-384, SHA-512
* @return String value of hash. (Variable length dependent on hash algorithm used)
* @throws IOException If file is invalid.
* @throws HashTypeException If no supported or valid hash algorithm was found.
*/
public String getHash(String file, String hashAlgo) throws IOException, HashTypeException {
StringBuffer hexString = null;
try {
MessageDigest md = MessageDigest.getInstance(validateHashType(hashAlgo));
FileInputStream fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
fis.close();
byte[] mdbytes = md.digest();
hexString = new StringBuffer();
for (int i = 0; i < mdbytes.length; i++) {
hexString.append(Integer.toHexString((0xFF & mdbytes[i])));
}
return hexString.toString();
} catch (NoSuchAlgorithmException | HashTypeException e) {
throw new HashTypeException("Unsuppored Hash Algorithm.", e);
}
}
/**
*获取文件的哈希值。
*
*@param file String path+要获取哈希的文件名。
*@param hashAlgo要使用的哈希算法
*支持的算法有:
*MD2,MD5
*SHA-1
*SHA-256、SHA-384、SHA-512
*@返回散列的字符串值。(可变长度取决于使用的哈希算法)
*@在文件无效时引发IOException。
*@如果未找到受支持或有效的哈希算法,则引发HashTypeException。
*/
公共字符串getHash(字符串文件,字符串hashAlgo)抛出IOException,HashTypeException{
StringBuffer-hexString=null;
试一试{
MessageDigest md=MessageDigest.getInstance(validateHashType(hashAlgo));
FileInputStream fis=新的FileInputStream(文件);
字节[]数据字节=新字节[1024];
int nread=0;
而((nread=fis.read(数据字节))!=-1){
md.update(数据字节,0,nread);
}
fis.close();
byte[]mdbytes=md.digest();
hexString=新的StringBuffer();
对于(int i=0;i
有没有更优化的方法来获取文件哈希?我正在寻找极限性能,不确定我是否以最佳方式实现了这一点。我看到了一些潜在的性能改进。一种是使用
StringBuilder
而不是StringBuffer
;它与源代码兼容,但性能更高,因为它不同步。第二个(更重要的)是使用FileChannel
和java.nio
API而不是FileInputStream
——或者至少,将FileInputStream
包装在BufferedInputStream
中,以优化I/O。除了Ernest的答案之外:-
getInstance(validateHashType(hashAlgo))我认为这可以缓存在一个线程本地hashmap中,以validateHashType(hashAlgo)为键。制作MessageDigest需要时间,但您可以重用它们:从映射中获取实例后,在开始时调用reset()方法
查看java.lang.ThreadLocal的javadoc您分析过代码了吗?它的大部分时间花在哪里?