package cn.com.taiji.util.bigfile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.Method; import java.math.BigInteger; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.security.AccessController; import java.security.MessageDigest; import java.security.PrivilegedAction; /** * 文件md5值 * * version 1.0 */ public class FileMD5Util { private final static Logger logger = LoggerFactory.getLogger(FileMD5Util.class); public static String getFileMD5(File file) throws FileNotFoundException { String value = null; FileInputStream in = new FileInputStream(file); MappedByteBuffer byteBuffer = null; try { byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(byteBuffer); BigInteger bi = new BigInteger(1, md5.digest()); value = bi.toString(16); if (value.length() < 32) { value = "0" + value; } } catch (Exception e) { e.printStackTrace(); } finally { if (null != in) { try { in.getChannel().close(); in.close(); } catch (IOException e) { logger.error("get file md5 error!!!", e); } } if (null != byteBuffer) { freedMappedByteBuffer(byteBuffer); } } return value; } /** * 在MappedByteBuffer释放后再对它进行读操作的话就会引发jvm crash,在并发情况下很容易发生 * 正在释放时另一个线程正开始读取,于是crash就发生了。所以为了系统稳定性释放前一般需要检 查是否还有线程在读或写 * * @param mappedByteBuffer */ public static void freedMappedByteBuffer(final MappedByteBuffer mappedByteBuffer) { try { if (mappedByteBuffer == null) { return; } mappedByteBuffer.force(); AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { try { Method getCleanerMethod = mappedByteBuffer.getClass().getMethod("cleaner", new Class[0]); getCleanerMethod.setAccessible(true); sun.misc.Cleaner cleaner = (sun.misc.Cleaner) getCleanerMethod.invoke(mappedByteBuffer, new Object[0]); cleaner.clean(); } catch (Exception e) { logger.error("clean MappedByteBuffer error!!!", e); } logger.info("clean MappedByteBuffer completed!!!"); return null; } }); } catch (Exception e) { e.printStackTrace(); } } }