Java文件Hash类,实现对计算进度的监视以及多算法的同时计算

利用Java自带的MessageDigest来数据的Hash值非常方便,如:

Code
MessageDigest messageDigest  =  MessageDigest.getInstance( " MD5 " ); 
FileInputStream in 
=   new  FileInputStream(file); 
FileChannel ch 
=  in.getChannel(); 
MappedByteBuffer byteBuffer 
=  ch.map(FileChannel.MapMode.READ_ONLY,  0 , file.length()); 
messageDigest.update(byteBuffer); 
return  messageDigest.digest();  

 

但如果计算较大的数据则无法监视计算进度.于是我对数据的读取和处理进行了简单的封装,以达到通过注册监听器进行进度监视的目的.

关键部分代码如下:

code
     private   void  updateHash()  throws  IOException {
    
boolean  readToEnd  =  readLength  ==   0 ;
    
byte [] bytesBuf  =   new   byte [bufferSize];
    
int  readLen;
    
while  ((readToEnd  ||  readCount  <  readLength)
        
&&  (readLen  =  inputStream.read(bytesBuf))  >   0 ) {
        readCount 
+=  readLen;
        HashBuffer buf 
=   new  HashBuffer(bytesBuf, readLen, inputStream);
        
for  (HashProgressInterceptor itcp : ltcps) {
        itcp.bytesRead(buf, 
this );
        }
        
if  ( ! buf.isSkip()) {
        
for  (MessageDigest md : messageDigests) {
            md.update(buf.getData(), buf.getOffset(), buf.getLength());
        }
        }
    }
    byteArrayHash 
=   new   byte [messageDigests.length][];
    
for  ( int  i  =   0 ; i  <  messageDigests.length; i ++ ) {
        byteArrayHash[i] 
=  messageDigests[i].digest();
    }
    }

 

原理很简单,就是每读取一些数据就调用监听器方法并传入信息参数.


使用方法:

1.通过抽象类HashCalc的工厂方法获取实例.

2.注册监听器(如果需要监视进度).

3.调用getHexStringHash()或getByteArrayHash()取得结果,这两个方法的区别仅是结果的形式不同.第一次调用这两个方法其中之一时会进行计算并缓存结果,之后再调用将直接返回缓存中的值.

 

Example
import  idv.takamachi660.util.hash.HashBuffer;
import  idv.takamachi660.util.hash.HashCalc;
import  idv.takamachi660.util.hash.HashProgressInterceptor;
import  idv.takamachi660.util.hash.IHashCalc;

import  java.io.File;
import  java.io.IOException;
import  java.security.MessageDigest;

public   class  FileHashDemo {

    
public   static   void  main(String[] args)  throws  IOException {
    
long  startTime  =  System.currentTimeMillis();
    IHashCalc hash 
=  HashCalc.getFileInstance(
        
" your file name here " " MD5 " " SHA-1 " );
    hash.setBufferSize(
5242880 );
    
//  set buffer size to 5MB default value is 1MB
    hash.addHashProgressInterceptor( new  HashProgressInterceptor() {
        @Override
        
public   void  bytesRead(HashBuffer buffer, IHashCalc calc) {
        
long  finished  =  calc.getReadCount();
        
long  total  =  ((File) calc.getSource()).length();
        System.out.println(String.format(
" read %d bytes,%.2f%% " , buffer
            .getLength(), finished 
*   100.0   /  total));
        }
    });
    MessageDigest[] mds 
=  hash.getMessageDigests();
    String[] results 
=  hash.getHexStringHash();
    
for  ( int  i  =   0 ; i  <  mds.length; i ++ ) {
        System.out.println(mds[i].getAlgorithm() 
+   " = "   +  results[i]);
    }
    System.out.println(
" spend  "   +  (System.currentTimeMillis()  -  startTime)
        
+   " Millis " );
    }
}

 

 

 

其他内容见doc.

/Files/takamachi660/Java_HashTools.zip

你可能感兴趣的:(java)