2012-02-17 176 views
7

我正在使用Java爲某些文件生成MD5哈希。我需要爲幾個文件生成一個MD5,總大小約爲1 GB。 這裏是我的代碼:使用Java爲使用Java的大文件生成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) { 
      // ... 
     } 
    } 

}

這似乎永遠運行。 我該如何提高效率?

+1

在'finally'塊中''inputStream''不可能是'null'。 – BalusC 2012-02-17 02:42:49

+1

無緩衝的IO緩慢,11時消息。 – 2012-04-16 16:55:56

回答

18

您可能需要使用Fast MD5庫。它比Java的內置MD5提供更快和獲得哈希很簡單,只要:

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

注意,速度慢也可能是由於較慢的文件I/O。

11

我重寫使用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) { 

     } 
    } 
} 

在我的機器,它需要大約30秒生成MD5碼爲一個大文件,當然我測試你的代碼好,結果表明nio並沒有提高程序的性能。

然後,我嘗試分別獲取io和md5的時間,統計數據表明緩慢的文件io是瓶頸,因爲大約5/6的時間用於io。

通過使用@Sticky提到的Fast MD5庫,生成md5代碼只需要15s,改進非常顯着。

0

每當速度是一個問題,你從一個URL下載文件想在同一時間來計算其MD5(即不保存文件,重新再讀只是爲了得到它的MD5),我的解決方案在https://stackoverflow.com/a/11189634/1082681可能會有幫助。它基於此線程中的Bloodwulf的代碼片段(謝謝!),並將其擴展一點。