挑戦する
JARファイル(> 1G)のチェックサムを計算するための高速アルゴリズムをPure-Javaで記述します。可能であれば、サードパーティライブラリを使用しないでください。
標準的な方法
ファイルのコンテンツ全体に MD5ダイジェストを使用します。
MessageDigest digest = MessageDigest . getInstance ( "MD5" ) ; <br/>
byte [ ] buf = new byte [ 1024 ] ; <br/>
int len = 0 ; <br/>
InputStream stream = new BufferedInputStream ( new FileInputStream ( new File ( "/path/to/jar/file" ) ) ) ; <br/>
while ( ( len = stream. read ( buf ) ) > 0 ) { <br/>
digest. update ( buf, 0 , len ) ; <br/>
} <br/>
stream. close ( ) ; <br/>
byte [ ] md5sum = digest. digest ( ) ; <br/>
ただし、JARにはアーカイブ内の各ファイルのCRCがすでに含まれているという事実を利用できます。
CRCシーケンスにのみMD5ダイジェストを使用します。
最終版
import java.io.* ; <br/>
import java.math.* ; <br/>
import java.security.* ; <br/>
import java.util.* ; <br/>
import java.util.jar.* ; <br/>
<br/>
public class JarFileChecksum { <br/>
private final File jarFile ; <br/>
<br/>
public JarFileChecksum ( File jarFile ) { <br/>
this . jarFile = jarFile ; <br/>
} <br/>
<br/>
public String getChecksum ( ) throws Exception { <br/>
MessageDigest digest = MessageDigest . getInstance ( "MD5" ) ; <br/>
JarFile jar = new JarFile ( jarFile ) ; <br/>
int crc ; <br/>
byte [ ] buf = new byte [ 4 ] ; <br/>
for ( Enumeration < JarEntry > e=jar. entries ( ) ; e. hasMoreElements ( ) ; ) { <br/>
JarEntry entry = e. nextElement ( ) ; <br/>
// CRC integer <br/>
crc = ( int ) entry. getCrc ( ) ; <br/>
// split crc to bytes <br/>
buf [ 0 ] = ( byte ) ( ( crc >> 24 ) & 0xFF ) ; <br/>
buf [ 1 ] = ( byte ) ( ( crc >> 16 ) & 0xFF ) ; <br/>
buf [ 2 ] = ( byte ) ( ( crc >> 8 ) & 0xFF ) ; <br/>
buf [ 3 ] = ( byte ) ( crc & 0xFF ) ; <br/>
digest. update ( buf ) ; <br/>
} <br/>
jar. close ( ) ; <br/>
byte [ ] md5sum = digest. digest ( ) ; <br/>
// String <br/>
BigInteger bigInt = new BigInteger ( 1 , md5sum ) ; <br/>
return bigInt. toString ( 16 ) ; <br/>
} <br/>
}
テスト
テストでは、1.6G JARファイル、37,000ファイル、1,500ディレクトリが選択されました。
最初の方法:140秒
2番目の方法:0.5秒