【问题标题】:Very slow to generate MD5 for large file using Java使用Java为大文件生成MD5非常慢
【发布时间】:2012-03-08 11:29:19
【问题描述】:

我正在使用 Java 为某些文件生成 MD5 哈希。我需要为几个总大小约为 1 GB 的文件生成一个 MD5。 这是我的代码:

private String generateMD5(SequenceInputStream inputStream){
    if(inputStream==null){
        return null;
    }
    MessageDigest md;
    try {
        int read =0;
        byte[] buf = new byte[2048];
        md = MessageDigest.getInstance("MD5");
        while((read = inputStream.read(buf))>0){
            md.update(buf,0,read);
        }
        byte[] hashValue = md.digest();
        return new String(hashValue);
    } catch (NoSuchAlgorithmException e) {
        return null;
    } catch (IOException e) {
        return null;
    }finally{
        try {
            if(inputStream!=null)inputStream.close();
        } catch (IOException e) {
            // ...
        }
    } 

}

这似乎永远运行。 如何提高效率?

【问题讨论】:

  • 嘘,inputStream 不可能是 nullfinally 块中。
  • 无缓冲 IO 很慢,11 点消息。

标签: java performance file md5 checksum


【解决方案1】:

您可能想要使用Fast MD5 库。它比 Java 的内置 MD5 提供程序要快得多,并且获取哈希就像这样简单:

String hash = MD5.asHex(MD5.getHash(new File(filename)));

请注意,速度慢也可能是由于文件 I/O 速度慢。

【讨论】:

    【解决方案2】:

    我用nio重写了你的代码,代码有点像下面:

    private static String generateMD5(FileInputStream inputStream){
        if(inputStream==null){
    
            return null;
        }
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
            FileChannel channel = inputStream.getChannel();
            ByteBuffer buff = ByteBuffer.allocate(2048);
            while(channel.read(buff) != -1)
            {
                buff.flip();
                md.update(buff);
                buff.clear();
            }
            byte[] hashValue = md.digest();
            return new String(hashValue);
        }
        catch (NoSuchAlgorithmException e)
        {
            return null;
        } 
        catch (IOException e) 
        {
            return null;
        }
        finally
        {
            try {
                if(inputStream!=null)inputStream.close();
            } catch (IOException e) {
    
            }
        } 
    }
    

    在我的机器上,生成一个大文件的md5代码大约需要30s,当然我也测试了你的代码,结果表明nio并没有提高程序的性能。

    然后,我尝试分别获取io和md5的时间,统计表明慢文件io是瓶颈,因为大约有5/6的时间用于io。

    使用@Sticky提到的Fast MD5库,生成md5代码仅需15s,提升显着。

    【讨论】:

      【解决方案3】:

      当速度成为问题时,您从 URL 下载文件并且想同时计算其 MD5(即不保存文件,重新打开并再次读取以获取其 MD5) ,我在https://stackoverflow.com/a/11189634/1082681 的解决方案可能会有所帮助。它基于 Bloodwulf 的代码 sn-p here in this thread(谢谢!),只是对其进行了一点扩展。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-29
        • 1970-01-01
        相关资源
        最近更新 更多