使用Java为大文件生成MD5非常慢

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

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) { // ... } } 

}

这似乎永远存在。 我怎样才能提高效率?

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

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

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

我用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代码大约需要30秒,当然我也会测试你的代码,结果表明nio不会提高程序的性能。

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

通过使用@Sticky提到的Fast MD5库,生成md5代码只需15秒,这一改进非常显着。

每当速度成为问题并且您从URL下载文件想要同时计算其MD5(即不保存文件,重新打开并再次读取以获取其MD5)时,我的解决方案位于https:// stackoverflow。 com / a / 11189634/1082681可能会有所帮助。 它基于Bloodwulf的代码片段在这个post中(谢谢!)并且只是扩展了一下。