使用RandomAccessFile获取文件的MD5值

来源:互联网 发布:淘宝火车票网上订票 编辑:程序博客网 时间:2024/06/06 02:43
不同于使用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);    }
1 0
原创粉丝点击