使用NIO的內存映射計算超大文件的MD5
在最近的開發及原有方案的改良中,一個feture就是加快對GB級大文件的讀取和計算MD5的速度。這是一個IO密集和CPU密集的耗時操作,
在無法硬性提高CPU的條件下,我考慮從IO上如何提高速率。
超大文件的MD5計算,需要分段將文件中的內存更新到MessageDigest中。(註:MessageDigest的實例不能共享,CSDN等博客上介紹MD5計算的demo,將MessageDigest設置為單例模式,單線程計算一個文件的MD5不會出錯,多線程計算就會出問題了。)
Java的NIO中提供了內存映射,通過將文件的一部分映射到內存中,可以一定程度地提高IO速率,從提高整體的效率。使用NIO的內存映射需要注意
內存的釋放(之前未釋放內存,在100GB級的文件測試中,拋出了OOM錯誤)。
分段計算MD5的代碼實現如下:
public static byte[] getMD5Digits(File file) throws IOException { FileInputStream inputStream = new FileInputStream(file); FileChannel channel = inputStream.getChannel(); try { MessageDigest messagedigest = MessageDigest.getInstance("MD5"); long position = 0; long remaining = file.length(); MappedByteBuffer byteBuffer = null; while (remaining > 0) { long size = Integer.MAX_VALUE / 2; if (size > remaining) { size = remaining; } byteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, position, size); messagedigest.update(byteBuffer); position += size; remaining -= size; } unMapBuffer(byteBuffer, channel.getClass()); return messagedigest.digest(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } finally { channel.close(); inputStream.close(); } }
手動釋放映射內存的實現如下:
/** * JDK不提供MappedByteBuffer的釋放,但是MappedByteBuffer在Full GC時才被回收,通過手動釋放的方式讓其回收 * * @param buffer */ public static void unMapBuffer(MappedByteBuffer buffer, Class channelClass)throwsIOException{ if (buffer == null) { return; } Throwable throwable = null; try { Method unmap = channelClass.getDeclaredMethod("unmap", MappedByteBuffer.class); unmap.setAccessible(true); unmap.invoke(channelClass, buffer); } catch (NoSuchMethodException e) { throwable = e; } catch (IllegalAccessException e) { throwable = e; } catch (InvocationTargetException e) { throwable = e; } if (throwable != null) { throw new IOException("MappedByte buffer unmap error", throwable); } }
※用戶體驗設計從業者有沒有所謂的 35 歲中年危機?
※慧川智能發布首款視頻理解API,要讓AI真正取代「剪片子」的人類?
※德國電子政務通信系統組件存在多個嚴重漏洞可導致政府交換數據泄露
※台灣 Gogoro 2 電動摩托車開始交車,預購數破 13000 台創紀錄
※浪潮湧動,門窗企業該轉型革新還是堅守傳統?
TAG:推酷 |
※具備語義與位置雙重映射,INDEMIND發布混合現實產品MELLO,眾籌價3399元
※映射和修改工具來到PC上的BLOPS 3
※使用IDAPython自動映射二進位文件替換默認函數名
※HTTPS為什麼可以穿越NAT埠映射設備?
※BigOne將支持EOS主網映射
※MyBatis框架之SQL映射和動態SQL
※動動手指 Bepal Pro S 硬體錢包輕鬆實現EOS一鍵映射
※將2D圖像人物實時映射3D模型,Facebook開源DensePose技術
※關於支持EOS主網映射.交易所的收集CEO.數字幣.龍網火幣的支持
※ZB.com幫你安全完成EOS映射
※Facebook最新開源,普通RGB相機即可實時映射3D模型
※ARKit 1.5 demo展示了iOS 11.3中的垂直平面映射升級
※Magic Leap系統為多人MR共享增加映射融合特性
※實現mybatis框架SQL映射文件SQL片段
※億萬資產即將歸零!一文讀懂EOS映射
※微軟Build開發者大會發布新應用 可將手機鏡像映射到PC
※Occipital推出MR創作工具Bridge Engine,實現密實3D映射
※淺談VPN和埠映射異同
※深入淺出MyBatis:「映射器」全了解
※三星對Galaxy S8/S9的Bixby鍵開放重新映射功能