`

Java 自带MD5 校验算法,别上当

 
阅读更多

前天第一次发表博客到论坛,关于Java文件监控一文,帖子地址在:http://www.iteye.com/topic/1127281

评论的朋友很多,下载代码的朋友很不少,感谢在论坛上看我帖子的朋友,还有回复评论的朋友,给我提供建议的朋友。

 

从这些建议中,虽然语言简短,但是却有的是一语中的,这里说一下一下关于帖子的代码中HashFile中的MD5文件校验算法,

该算法是使用Java自带的MessageDigest类,测试结果,获取一个2G文件的MD5码,耗时 971秒,这效率太给力了,可以用坑爹来形容,所以用MD5文件校验码来判断文件是否被修改,对于小文件来说可能还合适,要是对大文件来说,好吧,撞墙死了算了!

 

HashFile中的代码是这样子的:

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;

public class HashFile {  
  
    /** 
     * @param args 
     */  
    public static char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7',  
            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 
  
    public static String getHash(String fileName, String hashType)  
            throws Exception {  
        InputStream fis;  
        fis = new FileInputStream(fileName);  
        byte[] buffer = new byte[1024];  
        MessageDigest md5 = MessageDigest.getInstance(hashType);  
        int numRead = 0;  
        while ((numRead = fis.read(buffer)) > 0) {  
            md5.update(buffer, 0, numRead);  
        }  
        fis.close();  
        return toHexString(md5.digest());  
    }  
  
    public static String toHexString(byte[] b) {  
        StringBuilder sb = new StringBuilder(b.length * 2);  
        for (int i = 0; i < b.length; i++) {  
            sb.append(hexChar[(b[i] & 0xf0) >>> 4]);  
            sb.append(hexChar[b[i] & 0x0f]);  
        }  
        return sb.toString();  
    }  
}  

 

测试结果:


真给力啊,超过2G,效率变成这样 !

好吧,自带的MD5算法,上当了,对于检查文件是否更新这个问题来说,现在我使用的解决办法是File 类的lastModified方法,代码这样

	private String getHash(String fp){
		File file = new File(fp);
		return String.valueOf(file.lastModified());
	}

 通过比较文件的最后修改时间来判断文件是否更新,对大文件也轻松拿下,

测试结果是这样:



 当然针对不同问题肯定是有不同的解决办法,写这个博客的目的是告诉大家不要盲目相信JDK,Java自带的东西也有一定适用范围,有局限性,珍惜生命,请不要盲目相信JDK

 

分析原来HashFile代码,获取MD5校验码的瓶颈是出现在

public static String getHash(String fileName, String hashType)  
            throws Exception {  
        InputStream fis;  
        fis = new FileInputStream(fileName);  
        byte[] buffer = new byte[1024];  
        MessageDigest md5 = MessageDigest.getInstance(hashType);  
        int numRead = 0;  
        while ((numRead = fis.read(buffer)) > 0) {  //瓶颈
            md5.update(buffer, 0, numRead);  
        }  
        fis.close();  
        return toHexString(md5.digest());  
    }  

 在上面代码中,while循环N次,2G的文件,循环1024 * 1024  * 2 次,不给力!

分享到:
评论
1 楼 admade 2016-03-11  
   很不错

相关推荐

Global site tag (gtag.js) - Google Analytics