4

我正在尝试尽快获取文件的哈希值。我有一个程序可以散列大量数据(100GB+),其中包含随机文件大小(每个文件从几 KB 到 5GB+),在少数文件到几十万个文件之间的任何地方。

该程序必须支持所有 Java 支持的算法(MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512)。

目前我使用:

/**
 * 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);
    }
}

有没有更优化的方法来获取文件哈希?我正在寻找极致的性能,但不确定我是否已经采取了最好的方式。

4

2 回答 2

5

我看到了许多潜在的性能改进。一种是使用StringBuilder代替StringBuffer;它是源兼容的,但性能更高,因为它是不同步的。第二个(更重要的)是使用FileChanneljava.nioAPI 而不是FileInputStream- 或至少将其包装FileInputStream在 aBufferedInputStream中以优化 I/O。

于 2013-04-10T17:49:41.627 回答
1

除了欧内斯特的回答:- MessageDigest.getInstance(validateHashType(hashAlgo)) 我认为这可以缓存在线程本地哈希图中, validateHashType(hashAlgo) 作为键。制作 MessageDigest 需要时间,但您可以重用它们:在从 Map 获取实例后在开始时调用 reset() 方法。

请参阅 java.lang.ThreadLocal 的 javadoc

于 2013-05-20T21:30:44.240 回答