在项目中经常需要使用计算文件的md5,用作一些用途,md5计算算法,通常在网络上查询时,一般给的算法是读取整个文件的字节流,然后计算文件的md5,这种方式当文件较大,且有很大并发量时,则可能导致内存打爆掉。所以如下代码提供了几种方式。并通过计算一个323M的文件的md5和大小给出了,GC的一些信息

代码

/*
* Copyright (C) 2016. All Rights Reserved.
*/
package me.nabil.mixed; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; /**
* md5加密类
*/
public class Md5Util { private static final Logger LOGGER = LoggerFactory.getLogger(Md5Util.class); protected static final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f'}; /**
* 将二进制数据进行md5加密
*
* @param data 文件二进制数据
* @return md5加密码
*/
public static String getMd5ByByte(byte[] data) {
try {
char[] str;
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(data);
byte[] md = mdTemp.digest();
int j = md.length;
str = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
} return new String(str);
} catch (Exception e) {
LOGGER.error("Error occurred when making MD5 for data file", e);
return null;
}
} /**
* 文件对象
*
* @param file
* @return
*/
public static String getMD5ByFile(File file) {
FileInputStream fis = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
fis = new FileInputStream(file);
byte[] buffer = new byte[8192];
int length = -1;
System.out.println("开始算");
while ((length = fis.read(buffer)) != -1) {
md.update(buffer, 0, length);
}
System.out.println("算完了");
return bytesToString(md.digest());
} catch (IOException ex) {
LOGGER.info(ex.getMessage(), ex);
return null;
} catch (NoSuchAlgorithmException e) {
LOGGER.info(e.getMessage(), e);
return null;
} finally {
try {
fis.close();
} catch (IOException ex) {
LOGGER.info(ex.getMessage(), ex);
}
}
} /**
* bytesToString
*
* @param data
* @return
*/
public static String bytesToString(byte[] data) {
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f'};
char[] temp = new char[data.length * 2];
for (int i = 0; i < data.length; i++) {
byte b = data[i];
temp[i * 2] = hexDigits[b >>> 4 & 0x0f];
temp[i * 2 + 1] = hexDigits[b & 0x0f];
}
return new String(temp);
} /**
* main
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String path = "/path/to/file"; // 一个323M的文件路径 // 1. 流处理
System.out.println(getMD5ByFile(new File(path)) + ":" + FileUtils.sizeOf(new File(path))); // 2. common-codec
System.out.println(DigestUtils.md5Hex(new FileInputStream(path)) + ":" + FileUtils.sizeOf(new File(path))); // 3. 全部读进内存
byte[] data = FileUtils.readFileToByteArray(new File(path));
System.out.println(getMd5ByByte(data) + ":" + data.length); }
}

分析

以上三种方式,通过注释其他两种,只运行其中一种的方式来给出JVM的一些信息

运行时加入参数jvm参数:

-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime

1. 8M-buffer流处理

0.151: Total time for which application threads were stopped: 0.0000535 seconds, Stopping threads took: 0.0000072 seconds
0.151: Total time for which application threads were stopped: 0.0000428 seconds, Stopping threads took: 0.0000083 seconds
Connected to the target VM, address: '127.0.0.1:63630', transport: 'socket'
0.314: Total time for which application threads were stopped: 0.0001357 seconds, Stopping threads took: 0.0000145 seconds
0.417: Total time for which application threads were stopped: 0.0001063 seconds, Stopping threads took: 0.0000169 seconds
开始算
1.442: Total time for which application threads were stopped: 0.0221453 seconds, Stopping threads took: 0.0219728 seconds
算完了
Disconnected from the target VM, address: '127.0.0.1:63630', transport: 'socket'
aa3858dfbc48daab4b891e112d5396fc:323251542
Heap
PSYoungGen total 38400K, used 6658K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
eden space 33280K, 20% used [0x0000000795580000,0x0000000795c00b00,0x0000000797600000)
from space 5120K, 0% used [0x0000000797b00000,0x0000000797b00000,0x0000000798000000)
to space 5120K, 0% used [0x0000000797600000,0x0000000797600000,0x0000000797b00000)
ParOldGen total 87552K, used 0K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
object space 87552K, 0% used [0x0000000740000000,0x0000000740000000,0x0000000745580000)
Metaspace used 3560K, capacity 4728K, committed 4864K, reserved 1056768K
class space used 386K, capacity 424K, committed 512K, reserved 1048576K Process finished with exit code 0

2. apache common-codec的结果

0.184: Total time for which application threads were stopped: 0.0000615 seconds, Stopping threads took: 0.0000078 seconds
0.185: Total time for which application threads were stopped: 0.0000279 seconds, Stopping threads took: 0.0000056 seconds
0.640: Total time for which application threads were stopped: 0.0001445 seconds, Stopping threads took: 0.0000329 seconds
0.891: Total time for which application threads were stopped: 0.0001546 seconds, Stopping threads took: 0.0000383 seconds
1.904: Total time for which application threads were stopped: 0.0102225 seconds, Stopping threads took: 0.0101437 seconds
4.580: Total time for which application threads were stopped: 0.0001097 seconds, Stopping threads took: 0.0000165 seconds
aa3858dfbc48daab4b891e112d5396fc:323251542
Heap
PSYoungGen total 38400K, used 9508K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
eden space 33280K, 28% used [0x0000000795580000,0x0000000795ec92b8,0x0000000797600000)
from space 5120K, 0% used [0x0000000797b00000,0x0000000797b00000,0x0000000798000000)
to space 5120K, 0% used [0x0000000797600000,0x0000000797600000,0x0000000797b00000)
ParOldGen total 87552K, used 0K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
object space 87552K, 0% used [0x0000000740000000,0x0000000740000000,0x0000000745580000)
Metaspace used 3616K, capacity 4792K, committed 5120K, reserved 1056768K
class space used 391K, capacity 424K, committed 512K, reserved 1048576K
Disconnected from the target VM, address: '127.0.0.1:63674', transport: 'socket'

3. 全部读进内存再计算

0.161: Total time for which application threads were stopped: 0.0000584 seconds, Stopping threads took: 0.0000190 seconds
0.161: Total time for which application threads were stopped: 0.0000407 seconds, Stopping threads took: 0.0000054 seconds
0.356: Total time for which application threads were stopped: 0.0001168 seconds, Stopping threads took: 0.0000177 seconds
0.860: [GC (Allocation Failure) [PSYoungGen: 21892K->4950K(38400K)] 21892K->25438K(125952K), 0.0187028 secs] [Times: user=0.01 sys=0.01, real=0.02 secs]
0.879: Total time for which application threads were stopped: 0.0189020 seconds, Stopping threads took: 0.0000150 seconds
4.411: Total time for which application threads were stopped: 0.0445206 seconds, Stopping threads took: 0.0435764 seconds
4.694: Total time for which application threads were stopped: 0.0003998 seconds, Stopping threads took: 0.0000154 seconds
5.695: Total time for which application threads were stopped: 0.0001298 seconds, Stopping threads took: 0.0000841 seconds
aa3858dfbc48daab4b891e112d5396fc:323251542
Heap
PSYoungGen total 38400K, used 22181K [0x0000000795580000, 0x000000079a080000, 0x00000007c0000000)
eden space 33280K, 51% used [0x0000000795580000,0x0000000796653bd0,0x0000000797600000)
from space 5120K, 96% used [0x0000000797600000,0x0000000797ad58d0,0x0000000797b00000)
to space 5120K, 0% used [0x0000000799b80000,0x0000000799b80000,0x000000079a080000)
ParOldGen total 863744K, used 827683K [0x0000000740000000, 0x0000000774b80000, 0x0000000795580000)
object space 863744K, 95% used [0x0000000740000000,0x0000000772848dd8,0x0000000774b80000)
Metaspace used 3663K, capacity 4792K, committed 5120K, reserved 1056768K
class space used 393K, capacity 424K, committed 512K, reserved 1048576K
Disconnected from the target VM, address: '127.0.0.1:63717', transport: 'socket' Process finished with exit code 0

结论

可以看出前两种方案是可取的,第三种方式内存占用太高。

Java中比较不同的MD5计算方式的更多相关文章

  1. JAVA中单例模式的几种实现方式

    1 线程不安全的实现方法 首先介绍java中最基本的单例模式实现方式,我们可以在一些初级的java书中看到.这种实现方法不是线程安全的,所以在项目实践中如果涉及到线程安全就不会使用这种方式.但是如果不 ...

  2. Java中HashMap遍历的两种方式

    Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...

  3. JAVA中集合输出的四种方式

    在JAVA中Collection输出有四种方式,分别如下: 一) Iterator输出. 该方式适用于Collection的所有子类. public class Hello { public stat ...

  4. java中数组复制的两种方式

    在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...

  5. JAVA中的四种JSON解析方式详解

    JAVA中的四种JSON解析方式详解 我们在日常开发中少不了和JSON数据打交道,那么我们来看看JAVA中常用的JSON解析方式. 1.JSON官方 脱离框架使用 2.GSON 3.FastJSON ...

  6. Java中的float、double计算精度问题

    java中的float.double计算存在精度问题,这不仅仅在java会出现,在其他语言中也会存在,其原因是出在IEEE 754标准上. 而java对此提供了一个用于浮点型计算的类——BigDeci ...

  7. java中float/double浮点数的计算失精度问题(转)

    如果我们编译运行下面这个程序会看到什么? public class Test  {    public static void main(String args[]) {                ...

  8. Java 中UDP原理机制及实现方式介绍(建议阅读者阅读前了解下Java的基础知识,一方便理解)

    1.基本概念介绍: 首先得简单介绍下UDP. UDP( User Datagram Protocol )协议是用户数据报,在网络中它与TCP协议一样用于处理数据包.在OSI模型中,在第四层——传输层, ...

  9. Java中String对象两种赋值方式的区别

    本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...

随机推荐

  1. 如果你也和我一样,OSX反应慢,不妨试试这个

  2. Java中数据类型及其之间的转换

    Java中数据类型及其之间的转换 基本的数据类型 基本类型有以下四种:1)int长度数据类型有:byte(8bits).short(16bits).int(32bits).long(64bits).2 ...

  3. C语言产生随机数

    rand产生随机数 #include"stdio.h" #include"stdlib.h" void main() { int i; for(i=0;i< ...

  4. WPF 任务栏图标闪烁提醒

    using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServi ...

  5. bootshrap会改变IE浏览器滚动条样式

    在某个小网站的开发中 客户一直抱怨在IE11中网页右边滚动条不一样 后来发现在IE11中,有2个页面滚动条会自动隐藏,一开始以为是浏览器默认行为,改了overflow:scroll后也没有用.仔细观察 ...

  6. ExtJS学习之路第六步:深入讨论组件Panel用法

    Panel加载页面 var myPanel=Ext.create('Ext.panel.Panel',{ bodyPadding: "15px 10px 0 10px", titl ...

  7. 响应式js幻灯片代码一枚

    网站搭建经常会用到js幻灯片轮播,放上几张上档次的美图,为你的爱站增添大气元素.经常看到一些js幻灯片代码,但是感觉不是很美观,有的也不支持自适应缩放,也即是响应式,现在智能手机的普及以及移动浏览器技 ...

  8. linux下搭建Nginx

    Linux上搭建nginx,及简单配置  在上家公司都是运维安装nginx,到新公司后代码开发完成部署测试服务器要求自己装nginx,研究了好久安装好之后,到正式上线还要自己安装,索性把安装步骤自己记 ...

  9. 第一次学习QT

    跟着大神学:http://www.cnblogs.com/tornadomeet/archive/2012/06/25/2561007.html

  10. POJ 1797 Heavy Transportation (Dijkstra变形)

    F - Heavy Transportation Time Limit:3000MS     Memory Limit:30000KB     64bit IO Format:%I64d & ...