您的位置:首页 > 其它

使用RandomAccessFile获取文件的MD5值

2016-01-15 20:13 411 查看
不同于使用FileInputStream和FileOutputStream读写文件,RadomAccessFile支持随机访问文件的方式。下面是官方的解释:
Allows reading from and writing to a file in a random-access manner.
This is different from the uni-directional sequential access that a {@link FileInputStream} or {@link FileOutputStream} provides.
If the file is opened in read/write mode, write operations are available as well.
The position of the next read or write operation can be moved forwards and backwards after every operation.

如何使用RandomAccessFile获取文件的MD5值:
1.通过MessageDigest.getInstance("MD5")得到MessageDigest实例。
2.创建RadomAccessFile的一个实例。
3.通过RadomAccessFile.read()读取文件,并调用MessageDigest.update()更新MessageDigest。
4.将MessageDigest转化为16进制的字符串(即MD5值)。

以下是相关代码:


public class MD5Util {
private static final int STREAM_BUFFER_LENGTH = 1024;
private static MessageDigest messagedigest = null;

static{
try{
messagedigest = MessageDigest.getInstance("MD5");
}catch(NoSuchAlgorithmException e){
System.err.println(String.format("Initialization error , MessageDigest is not support %s : %s",
MD5Util.class.getName(),e.getMessage()));
}
}

/**
*获取一般文件的md5值
*/
public static String getFileMD5(String path){
File file = new File(path);
if (!file.exists() || !file.isFile()) {
return null;
}
byte[] buffer = new byte[STREAM_BUFFER_LENGTH * 8];
RandomAccessFile rf = null;
int len;
try{
rf = new RandomAccessFile(path,"r");
while ((len = rf.read(buffer)) != -1){
messagedigest.update(buffer,0,len);
}
}catch (IOException e){
System.err.println(String.format("Class %s File %s can not read : %s",
MD5Util.class.getName(), file.getAbsolutePath(),e.getMessage()));
}finally {
if(rf != null){
try{
rf.close();
}catch (IOException e){
System.err.println(String.format("Class %s File %s's RandomAccessFile can not close : %s",
MD5Util.class.getName(), file.getAbsolutePath(),e.getMessage()));
}
}
}
BigInteger integer = new BigInteger(1, messagedigest.digest());
return integer.toString(16);
}


但是要计算上G文件的MD5时,计算时间大约要几秒,用户体验肯定不好。对此,可以通过计算大文件的几个特定部分来表示大文件的MD5值(但不是大文件的MD5值)。

相关代码如下:


public static String getSimpleMD5(String path) {
File file = new File(path);
if (!file.exists() || !file.isFile()) {
return null;
}
int len;
RandomAccessFile rf = null;
byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
try {
rf = new RandomAccessFile(path, "r");
if (file.length() > STREAM_BUFFER_LENGTH * 3) {
//开头读取一个KB
rf.seek(0);
rf.read(buffer);
messagedigest.update(buffer);

//文件中间开始读取一个KB
rf.seek(file.length() / 2);
rf.read(buffer);
messagedigest.update(buffer);

//文件结尾前读取一个KB
rf.seek(file.length() - STREAM_BUFFER_LENGTH);
rf.read(buffer);
messagedigest.update(buffer);
} else {
while ((len = rf.read(buffer)) != -1) {
messagedigest.update(buffer, 0, len);
}
}
} catch (IOException e) {
System.err.println(String.format("Class %s File %s can not read : %s",MD5Util.class.getName(), file.getAbsolutePath(), e.getMessage()));
} finally {
if (rf != null) {
try {
rf.close();
} catch (IOException e) {
System.err.println(String.format("Class %s File %s's RandomAccessFile can not close : %s",MD5Util.class.getName(), file.getAbsolutePath(), e.getMessage()));
}
}
}
BigInteger integer = new BigInteger(1, messagedigest.digest());
return integer.toString(16);
}

4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  md5