前天第一次发表博客到论坛,关于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(); } }
测试结果:
好吧,自带的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 次,不给力!