Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取文件哈希性能/优化_Java_Algorithm_File_Hash - Fatal编程技术网

Java 获取文件哈希性能/优化

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

我正在尽可能快地获取文件的哈希值。我有一个程序,它可以散列由随机文件大小(每个文件大小从几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 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

您分析过代码了吗?它的大部分时间花在哪里?