6.7 实例:文件校验
秉承程序员的执著,发现问题就要解决问题!既然我们已经看到了MySQL下载页面上的MD5信息,就要对其文件做MD5校验!通过下载页面下载MySQL Essential 5.1.38的Windows安装版(mysql-essential-5.1.38-win32.msi),并将其放置在D盘根目录下。接下来,我们要对这个文件做一次MD5校验。如果校验结果与下载页面上给出的MD5信息不一致,则说明文件在下载的过程中被篡改了!
这个校验并不复杂,我们分别通过testByMessageDigest()和testByDigestUtils()方法做校验处理,如代码清单6-22所示。
代码清单6-22 校验下载文件一致性
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Test;
/**
*消息摘要编码测试<br>
*用于校验文件的MD5值
*<pre>
*文件为mysql-essential-5.1.38-win32.msi
*存放于D盘根目录
*MD5值为5a077abefee447cbb271e2aa7f6d5a47
*</pre>
*@author梁栋
*@version 1.0
*@since 1.0
*/
public class MD5Test{
/**
*验证文件的MD5值
*@throws Exception
*/
@Test
public void testByMessageDigest()throws Exception{
//文件路径
String path="D:\mysql-essential-5.1.38-win32.msi";
//构建文件输入流
FileInputStream fis=new FileInputStream(new File(path));
//初始化MessageDigest,并指定MD5算法
DigestInputStream dis=new DigestInputStream(fis, MessageDigest.getInstance("MD5"));
//流缓冲大小
int buf=1024;
//缓冲字节数组
byte[]buffer=new byte[buf];
//当读到值大于-1就继续读
int read=dis.read(buffer,0,buf);
while(read>-1){
read=dis.read(buffer,0,buf);
}
//关闭流
dis.close();
//获得MessageDigest
MessageDigest md=dis.getMessageDigest();
//摘要处理
byte[]b=md.digest();
//十六进制转换
String md5hex=Hex.encodeHexString(b);
//验证
assertEquals(md5hex,"5a077abefee447cbb271e2aa7f6d5a47");
}
/**
*验证文件的MD5值
*@throws Exception
*/
@Test
public void testByDigestUtils()throws Exception{
//文件路径
String path="D:\mysql-essential-5.1.38-win32.msi";
//构建文件输入流
FileInputStream fis=new FileInputStream(new File(path));
//使用DigestUtils做MD5Hex处理
String md5hex=DigestUtils.md5Hex(fis);
//关闭流
fis.close();
//验证
assertEquals(md5hex,"5a077abefee447cbb271e2aa7f6d5a47");
}
}
既然两种方法都是MD5文件校验,那么会有什么差异呢?
从测试结果来说,一定都是通过,那么在效率上呢?如图6-10所示。
图 6-10 MD5文件校验处理测试结果
作者做了反复测试,其测试结果与上图基本相符,两种方法实现效率较为接近。
如果只是对文件做MD5校验,用Commons Codec来实现再合适不过了。对文件做MD5处理/校验,已经是一件很平常的事情了。相信上述简要的代码实现,对读者朋友一定会很有益处。