http://www.iteye.com/topic/1127319

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

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

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

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

HashFile中的代码是这样子的:


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

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

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

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

测试结果是这样:


 当然针对不同问题肯定是有不同的解决办法

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

  1. public static String getHash(String fileName, String hashType)
  2. throws Exception {
  3. InputStream fis;
  4. fis = new FileInputStream(fileName);
  5. byte[] buffer = new byte[1024];
  6. MessageDigest md5 = MessageDigest.getInstance(hashType);
  7. int numRead = 0;
  8. while ((numRead = fis.read(buffer)) > 0) {  //瓶颈
  9. md5.update(buffer, 0, numRead);
  10. }
  11. fis.close();
  12. return toHexString(md5.digest());
  13. }
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 次,不给力!

chimer回复

来个nio的简单版,看你们老是怀疑java慢

C++ MD5工具验证结果:

File: K:\Games\World of Warcraft\Data\common.MPQ
Size: 2226587191 bytes
Modified: 2008年11月19日 星期三, 12:57:24
MD5: CD9F9C5523F3BA3866B81CCC74ED6476

java运行结果,毫秒
耗时:12672,cd9f9c5523f3ba3866b81ccc74ed6476

核心代码

String hashType = "MD5";
  FileInputStream fStream = null;
  try {
   MessageDigest md5 = MessageDigest.getInstance(hashType);
   fStream = new FileInputStream(
     //"K:\\Games\\World of Warcraft\\Scan.dll");
     //"K:\\Games\\World of Warcraft\\Data\\patch-3.MPQ");
     "K:\\Games\\World of Warcraft\\Data\\common.MPQ");
   FileChannel fChannel = fStream.getChannel();
   ByteBuffer buffer = ByteBuffer.allocate(8*1024);
   long s = System.currentTimeMillis();
   for ( int count = fChannel.read( buffer ); count !=-1 ; count = fChannel.read( buffer )
    ) {
    buffer.flip();
    md5.update( buffer );
    if( !buffer.hasRemaining() ){
     //System.out.println("count:"+count);
     buffer.clear();
    }
   }
   s = System.currentTimeMillis() - s;
   System.out.println( "耗时:"+s+","+getString( md5.digest() ) );
   
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }finally{
   try {
    if( fStream!=null )
     fStream.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }

Java 自带MD5 校验文件的更多相关文章

  1. Java 自带MD5加密 Demo

    package demo; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; pub ...

  2. Java:基于MD5的文件监听程序

    前述和需求说明 和之前写的 Python:基于MD5的文件监听程序 是同样的功能,就不啰嗦了,就是又写了一个java版本的,可以移步 python 版本去看一下,整个的核心思路是一样的.代码已上传Gi ...

  3. java 自带md5加密

    package test; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; pub ...

  4. 关于JAVA自带MD5的方法

    有空再详细解释 import java.security.MessageDigest; public class MD5 { public final static String MD51(Strin ...

  5. WINDOWS自带md5校验工具

    WINDOWS自带的工具certutil.exe,   certutil -hashfile chropp.exe MD5; 就可以了

  6. MD5 校验文件

    https://blog.csdn.net/wudishine/article/details/42466831 MD5.h #ifndef MD5_H #define MD5_H #include ...

  7. Shell 对整个文件夹中的文件进行MD5校验 [转]

    查看本地文件的 MD5 命令:md5sum FileName查看home目录下所有文件的 MD5 码:cd ~find /home -type f -print0 | xargs -0 md5sum ...

  8. 文件夹进行MD5校验的实现算法

    每份相同数据(文件夹)都可以生成一份唯一的md5校验文件,我们可以通过直接校验整个数据文件夹的方法来确定数据是否有误. 1.针对整个文件夹生成md5校验文件方法: 以data文件夹为例,我们需要得到d ...

  9. NCBI SRA数据如何进行md5校验?

    下了一些sra数据库中的公共数据,因为pretech和aspera不稳定,稍微大点的文件经常传断,部分文件我只能通过本地下载再上传. 那么问题来了,sra没有md5校验,我怎么知道我数据的完整性,尤其 ...

随机推荐

  1. matlab学习GUI的基本操作

    在命令行窗口输入guide 单击确定后出现,可以选择控件来设计,然后可以保存 右击可以查看控件的所有属性 举一个简单的GUI实例---实现数据的传输 添加可编辑文本框 更改字体大小,string默认的 ...

  2. 三维地图中的A*寻路

    跟二维地图原理一样,只不过搜索方向多了,二维只搜8个方向,而三维要搜26个方向. 不懂的看我以前写的文章,这里直接贴代码: #include <iostream> #include < ...

  3. django rest-farme-work 的使用(3)

    请求和响应 Requests and Responses 从这一片来说,我们将真正开始覆盖REST框架的核心.我们来介绍一些基本的构建块 Request objects REST框架引入了一个Requ ...

  4. Linux 中常用的基础命令二

    1.Linux文件分层结构  FHS:Linux有一个组织叫LSB定义的Linux发行版基础目录名称命名法则及功用规定,这种标准叫FHS文件系统层级标准./bin   存放可执行的二进制程序,管理员和 ...

  5. Python for Tkinter

    # tkinter常用组件- 按钮 - button(按钮组件) - RadioButton(单选框组件) - CheckButton(选择按钮组件) - Listbox(列表框组件) - 文本输入组 ...

  6. c++之vector使用

    Vector是向量模板,C++ STL之一(本质上是一个动态数组).vector是一个动态生长的数组,一开始vector为空时,会给一个初始化的容量 (就是允许的添加个数并申请好内存),当往添加的元素 ...

  7. android 异常解决方案汇总

    1)异常:Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法) 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来. 2.将引用的第三方 ...

  8. 0112centos上面l安装卸载mysq

    http://www.centoscn.com/CentosServer/sql/2015/0409/5127.html常用命令cat /etc/issuerpm -qa | grep mysqlyu ...

  9. rabbitMQ学习笔记(一)Windows 与Linux下rabbitMQ的安装

    版权声明:本文为博主原创文章,未经博主允许不得转载. Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definiti ...

  10. Hibernate单向关联N-N

    单向N-N关联必须使用连接表. Company实体: package com.ydoing.hibernate5; import java.util.HashSet; import java.util ...