md5 大文件

发布时间:2022-07-02 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了md5 大文件脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

测试 mail.rar , 一个1.59GB 的大文件,结果如下: // 分别测试3次,下面是测试结果; 我的电脑Intel i5 4核, 8G 内存; 不运行此程序且 不做任何操作 的时候, 观察发现: cpu 10%, mem 70% // md5ByJavaIO , 观察发现,大概的平均是: cpu 35%, mem 71% // md5:8ba6b147475af653bc4609d4cDF72148 time:74s 74s 74s; 测试N多次都是74s, 非常稳定

// md5ByFileChannel , 观察发现,大概的平均是: cpu 31%, mem 71% // md5:8ba6b147475af653bc4609d4cdf72148 time:75s 72s 73s

// md5ByFileChannelAndMapPEdByteBuffer , 观察发现,大概的平均是: cpu 30%, mem 71% // md5:8ba6b147475af653bc4609d4cdf72148 time:52s 53s 54s

 

// fastMd5 , 观察发现,大概的平均是: cpu 31%, mem 80% // md5:8ba6b147475af653bc4609d4cdf72148 time:51s 52s 51s

// 实际计算时间的时候, 需要减去休眠的100 * 10, 即1s,

 

代码如下:


import com.twmacinta.util.MD5;import com.twmacinta.util.MD5OutputStream;import java.io.*;import java.nio.ByteBuffer;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.securITy.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5Util {    /**     * 默认的密码字符串组合,apache校验下载的文件的正确性用的就是默认的这个组合     */    PRotected static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};    protected static MessageDigest messagedigest = null;    static {        try {            messagedigest = MessageDigest.getInstance("MD5");        } catch (NoSuchAlgorithmException nSAEx) {            System.err.println(MD5Util.class.getName() + "初始化失败,MessageDigest不支持MD5Util。");            nsaex.printStackTrace();        }    }    public static void main(String[] args) throws IOException {        long begin = System.currentTimeMillis();        File Big = new File("D:\office2013破解版.ISO"); // 810M//        big = new File("C:\Users\xd\Desktop\工作重要资料\xxx.zip"); //  2.25G; 但不能超过2G, 否则    at java.base/sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:994)        big = new File("D:\lk\mail.rar");// 1.59G        String md5 = null;        // 获取文件的 md5; 如果是仅仅是获取字符串的md5, 当然不需要这么复杂。。        for (int i = 0; i < 10; i++) {//            md5 = md5ByJavaIO(big); // java io 的方式//            md5 = md5ByFileChannel(big); // java nio 的方式//            md5 = md5ByFileChannelAndMappedByteBuffer(big); // fast md5            md5 = fastMd5(big);            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }        }        long end = System.currentTimeMillis();        System.out.println("md5:" + md5 + " time:" + ((end - begin) / 1000) + "s");        // 分别测试3次,下面是测试结果; 我的脑是 intel i5 4核, 8G 内存;  不运行此程序且 不做任何操作 的时候, 观察发现: cpu 10%, mem 70%        // md5ByJavaIO  , 观察发现,大概的平均是: cpu 35%, mem 71%        // md5:8ba6b147475af653bc4609d4cdf72148 time:74s 74s 74s; 测试N多次都是74s, 非常稳定        // md5ByFileChannel  , 观察发现,大概的平均是: cpu 31%, mem 71%        // md5:8ba6b147475af653bc4609d4cdf72148 time:75s  72s  73s        // md5ByFileChannelAndMappedByteBuffer , 观察发现,大概的平均是: cpu 30%, mem内存几乎毫无增长; SSD是 读300M/S; 写入220K-2M        // md5:8ba6b147475af653bc4609d4cdf72148 time:52s 53s 54s        // fastMd5 , 观察发现,大概的平均是: cpu 开始有个高峰,后面趋于平稳,后面是30% ; 大概是80%, mem xxx %        // md5:8ba6b147475af653bc4609d4cdf72148 time:51s 52s 51s        // 实际计算时间的时候, 需要减去休眠的100 * 10, 即1s,    }    /**     * 适用于上G大的文件     *     * @param file     * @return     * @throws IOException     */    public static String md5ByFileChannelAndMappedByteBuffer(File file) throws IOException {        FileinputStream in = new FileInputStream(file);        FileChannel ch = in.getChannel();        MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());        messagedigest.update(byteBuffer);        in.close();        return bufferToHex(messagedigest.digest());    }    private static String md5ByFileChannel(File big) {        if (big == null) {            return null;        }        MessageDigest md;        FileInputStream inputStream = null;        try {            int read = 0;            inputStream = new FileInputStream(big);            md = MessageDigest.getInstance("MD5");            FileChannel channel = inputStream.getChannel();            ByteBuffer buff = ByteBuffer.allocate(2048);            while (channel.read(buff) != -1) {                buff.flip();                md.update(buff);                buff.clear();            }            return bufferToHex(md.digest());        } catch (NoSuchAlgorithmException e) {            return null;        } catch (IOException e) {            return null;        } finally {            try {                if (inputStream != null) inputStream.close();            } catch (IOException e) {            }        }    }    //    private String generateMD5(SequenceInputStream inputStream){    private static String md5ByJavaIO(File big) {        if (big == null) {            return null;        }        MessageDigest md;        InputStream inputStream = null;        try {            int read = 0;            inputStream = new FileInputStream(big);            byte[] buf = new byte[2048];            md = MessageDigest.getInstance("MD5");            while ((read = inputStream.read(buf)) > 0) {                md.update(buf, 0, read);            }            return bufferToHex(md.digest());        } catch (NoSuchAlgorithmException e) {            return null;        } catch (IOException e) {            return null;        } finally {            try {                if (inputStream != null) inputStream.close();            } catch (IOException e) {// ...            }        }    }    private static String fastMd5(File big) {        String md5Str = null;        try {            MD5OutputStream out = new MD5OutputStream(new com.twmacinta.io.NullOutputStream());            InputStream in = new BufferedInputStream(new FileInputStream(big));            byte[] buf = new byte[65536];// 65536 是最佳数值, 大于或小于这个数字都会 导致耗时增加, 不知道为什么..            int num_read;            long total_read = 0;            while ((num_read = in.read(buf)) != -1) {                total_read += num_read;                out.write(buf, 0, num_read);            }            md5Str = MD5.asHex(out.hash());            //System.out.println(md5Str + "  " + big);            in.close();            out.close();        } catch (Exception e) {            e.printStackTrace();        }        return md5Str;    }    public static String getMD5String(String s) {        return getMD5String(s.getBytes());    }    public static String getMD5String(byte[] bytes) {        messagedigest.update(bytes);        return bufferToHex(messagedigest.digest());    }    private static String bufferToHex(byte bytes[]) {        return bufferToHex(bytes, 0, bytes.length);    }    private static String bufferToHex(byte bytes[], int m, int n) {        StringBuffer stringbuffer = new StringBuffer(2 * n);        int k = m + n;        for (int l = m; l < k; l++) {            appendHexpair(bytes[l], stringbuffer);        }        return stringbuffer.toString();    }    private static void appendHexPair(byte BT, StringBuffer stringbuffer) {        char c0 = hexDigits[(bt & 0xf0) >> 4];        char c1 = hexDigits[bt & 0xf];        stringbuffer.append(c0);        stringbuffer.append(c1);    }    public static boolean checkPassword(String password, String md5PwdStr) {        String s = getMD5String(password);        return s.equals(md5PwdStr);    }}
 

 

可见,大文件的时候, 最好还是不要java IO到内存, 可能映射过程就需要比较久时间。NIO MPP是很好的选择。

 

另外, 我们是否可以继续提高 大文件md5 的计算速度呢? 据说 多线程分块校验。。

 

我感觉行不通; 

 

另外,这边使用了一个 fastMD5的库, 发现确实可以稍微提升一点速度。 fastMD5 主要作用,大概是 不要NIO, 直接普通FIleInputStream 即可。

 

md5 大文件

 

脚本宝典总结

以上是脚本宝典为你收集整理的md5 大文件全部内容,希望文章能够帮你解决md5 大文件所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。