手機版java,Java NIO 下

 2023-12-06 阅读 19 评论 0

摘要:內存映射文件 JAVA處理大文件,一般用BufferedReader,BufferedInputStream這類帶緩沖的IO類,不過如果文件超大的話,更快的方式是采用MappedByteBuffer。 MappedByteBuffer是NIO引入的文件內存映射方案,讀寫性能極高。NIO最主要的就是實現了對異步操

內存映射文件

JAVA處理大文件,一般用BufferedReader,BufferedInputStream這類帶緩沖的IO類,不過如果文件超大的話,更快的方式是采用MappedByteBuffer。

MappedByteBuffer是NIO引入的文件內存映射方案,讀寫性能極高。NIO最主要的就是實現了對異步操作的支持。其中一種通過把一個套接字通道(SocketChannel)注冊到一個選擇器(Selector)中,不時調用后者的選擇(select)方法就能返回滿足的選擇鍵(SelectionKey),鍵中包含了SOCKET事件信息。這就是select模型。

SocketChannel的讀寫是通過一個類叫ByteBuffer來操作的.這個類本身的設計是不錯的,比直接操作byte[]方便多了. ByteBuffer有兩種模式:直接/間接.間接模式最典型(也只有這么一種)的就是HeapByteBuffer,即操作堆內存 (byte[]).但是內存畢竟有限,如果我要發送一個1G的文件怎么辦?不可能真的去分配1G的內存.這時就必須使用”直接”模式,即 MappedByteBuffer,文件映射.

手機版java。先中斷一下,談談操作系統的內存管理:

一般操作系統的內存分兩部分:物理內存;虛擬內存.虛擬內存一般使用的是頁面映像文件,即硬盤中的某個(某些)特殊的文件.操作系統負責頁面文件內容的讀寫,這個過程叫”頁面中斷/切換”. MappedByteBuffer也是類似的,你可以把整個文件(不管文件有多大)看成是一個ByteBuffer。MappedByteBuffer 只是一種特殊的ByteBuffer,即是ByteBuffer的子類。 MappedByteBuffer 將文件直接映射到內存(這里的內存指的是虛擬內存,并不是物理內存)。通常,可以映射整個文件,如果文件比較大的話可以分段進行映射,只要指定文件的那個部分就可以。

概念

FileChannel提供了map方法來把文件影射為內存映像文件: MappedByteBuffer map(int mode,long position,long size); 可以把文件的從position開始的size大小的區域映射為內存映像文件,mode指出了 可訪問該內存映像文件的方式:

  • READ_ONLY,(只讀): 試圖修改得到的緩沖區將導致拋出 ReadOnlyBufferException.(MapMode.READ_ONLY)

  • java最新版本安裝包下載,READ_WRITE(讀/寫): 對得到的緩沖區的更改最終將傳播到文件;該更改對映射到同一文件的其他程序不一定是可見的。 (MapMode.READ_WRITE)

  • PRIVATE(專用): 對得到的緩沖區的更改不會傳播到文件,并且該更改對映射到同一文件的其他程序也不是可見的;相反,會創建緩沖區已修改部分的專用副本。 (MapMode.PRIVATE)

MappedByteBuffer是ByteBuffer的子類,其擴充了三個方法:

  • force():緩沖區是READ_WRITE模式下,此方法對緩沖區內容的修改強行寫入文件;

  • load():將緩沖區的內容載入內存,并返回該緩沖區的引用;

  • nio java,isLoaded():如果緩沖區的內容在物理內存中,則返回真,否則返回假;

案例對比

這里通過采用ByteBuffer和MappedByteBuffer分別讀取大小約為5M的文件”src/1.ppt”來比較兩者之間的區別,method3()是采用MappedByteBuffer讀取的,method4()對應的是ByteBuffer。

public static void method4(){RandomAccessFile aFile = null;FileChannel fc = null;try{aFile = new RandomAccessFile("src/1.ppt","rw");fc = aFile.getChannel();long timeBegin = System.currentTimeMillis();ByteBuffer buff = ByteBuffer.allocate((int) aFile.length());buff.clear();fc.read(buff);long timeEnd = System.currentTimeMillis();System.out.println("Read time: "+(timeEnd-timeBegin)+"ms");}catch(IOException e){e.printStackTrace();}finally{try{if(aFile!=null){aFile.close();}if(fc!=null){fc.close();}}catch(IOException e){e.printStackTrace();}}}

?

public static void method3(){RandomAccessFile aFile = null;FileChannel fc = null;try{aFile = new RandomAccessFile("src/1.ppt","rw");fc = aFile.getChannel();long timeBegin = System.currentTimeMillis();MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, aFile.length());long timeEnd = System.currentTimeMillis();System.out.println("Read time: "+(timeEnd-timeBegin)+"ms");}catch(IOException e){e.printStackTrace();}finally{try{if(aFile!=null){aFile.close();}if(fc!=null){fc.close();}}catch(IOException e){e.printStackTrace();}}}

?注:MappedByteBuffer有資源釋放的問題:被MappedByteBuffer打開的文件只有在垃圾收集時才會被關閉,而這個點是不確定的。

javanide下載。在Javadoc中這樣描述:A mapped byte buffer and the file mapping that it represents remian valid until the buffer itself is garbage-collected。

其余功能介紹

看完以上陳述,詳細大家對NIO有了一定的了解,下面主要通過幾個案例,來說明NIO的其余功能,下面代碼量偏多,功能性講述偏少。

Scatter/Gatter

分散(scatter)從Channel中讀取是指在讀操作時將讀取的數據寫入多個buffer中。因此,Channel將從Channel中讀取的數據“分散(scatter)”到多個Buffer中。

聚集(gather)寫入Channel是指在寫操作時將多個buffer的數據寫入同一個Channel,因此,Channel 將多個Buffer中的數據“聚集(gather)”后發送到Channel。

scatter / gather經常用于需要將傳輸的數據分開處理的場合,例如傳輸一個由消息頭和消息體組成的消息,你可能會將消息體和消息頭分散到不同的buffer中,這樣你可以方便的處理消息頭和消息體。

?

轉載于:https://www.cnblogs.com/shanhm1991/p/7473278.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/191379.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息