Java 自带MD5 校验文件

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

前天第一次发表博客到论坛,关于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());
 }

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

测试结果是这样:


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

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

Java代码  

  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();
   }
  }

时间: 2024-08-07 18:52:38

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

【我的Linux,我做主!】浅谈MD5校验文件完整一致性

目录:(一)MD5介绍(二)md5sum命令(三)实战演练 (一)MD5介绍(1.1)MD5即Message-Digest Algorithm 5(信息-摘要算法 第5版),用于确保信息传输完整一致.是计算机广泛使用的杂凑算法之一(又名:摘要算法.哈希算法),主流编程语言普遍已由MD5实现.将数据运算为另一固定长度值(十六进制的为32位),是杂凑算法的基础原理,MD5的前身有MD2.MD3和MD4.MD5的作用是大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把

自动校验文件夹及其内容shell程序(md5 校验文件夹中所有数据)

一.问题的来源有时候copy一些重要的数据,得到之后需要与原数据进行核对是否数据一致.这就需要进行校验. 二.问题的分析校验数据有多种方法,最简单的是使用文件的md5码进行校验.但是文件很多,手动的每个文件进行md5校验显然不合适,这就需要编写shell程序解决. 三.问题的解决通过shell程序解决文件校验问题1.通过命令得到文件md5值比如得到的数据文件夹为 data 文件夹则在data 文件夹中输入以下命令 find  ./ -type f  -print | xargs md5sum  

java 自带md5加密

package test; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Util { //第一种实现 public final static String MD5(String s) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','

MD5 校验文件

https://blog.csdn.net/wudishine/article/details/42466831 MD5.h #ifndef MD5_H #define MD5_H #include <string> #include <fstream> /* Type define */ typedef unsigned char byte; typedef unsigned long ulong; using std::string; using std::ifstream;

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

每份相同数据(文件夹)都可以生成一份唯一的md5校验文件,我们可以通过直接校验整个数据文件夹的方法来确定数据是否有误. 1.针对整个文件夹生成md5校验文件方法: 以data文件夹为例,我们需要得到data整个文件夹中的文件的md5校验值,我们通过shell程序对整个data文件夹中的文件进行md5校验. 通过如下命令获得整个data文件夹的md5校验文件: 1 cd data 2 find ./ -type f -print0 | xargs md5sum > data_temp.md5 3

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

查看本地文件的 MD5 命令:md5sum FileName查看home目录下所有文件的 MD5 码:cd ~find /home -type f -print0 | xargs -0 md5sum | sort >md5.txt查看当前目录下所有文件的 MD5 码:find ./ -type f -print0 | xargs -0 md5sum | sort >md5.txt 通过上述方法对 home 文件夹里数据生成一份 md5 校验文件这个 md5 文件就这可作为这个 home 文件夹

md5sum校验文件完整性

1.简介 MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改. MD5 全称是报文摘要算法(Message-Digest Algorithm 5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的“指纹”(或称“报文摘要”),不同的文件产生相 同的报文摘要的可能性是非常非常之小的. 在linux或Unix上,md5sum是用来计算和校验文件报文摘要的工具程序.一般来说,安装了Linux后,就会有md5sum这个工具,直接在命令行终端直接运行

Java 获取 文件md5校验码

讯雷下载的核心思想是校验文件的md5值,两个文件若md5相同则为同一文件. 当得到用户下载某个文件的请求后它根据数据库中保留的文件md5比对出拥有此文件的url, 将用户请求挂接到此url上并仿造一个虚假的断点续传请求,从若干url上将一个正常文件拼接出来. 查了下资料,java也可以实现文件md5校验码获取,代码如下: import java.io.File;import java.io.FileInputStream;import java.io.IOException;import jav

java生成MD5校验码

在Java中,java.security.MessageDigest (rt.jar中)已经定义了 MD5 的计算,所以我们只需要简单地调用即可得到 MD5 的128 位整数.然后将此 128 位计 16 个字节转换成 16 进制表示即可. 下面是一个可生成字符串或文件MD5校验码的例子,测试过,可当做工具类直接使用,其中最主要的是getMD5String(String s)和getFileMD5String(File file)两个方法,分别用于生成字符串的md5校验值和生成文件的md5校验值