MappedByteBuffer的使用
????????其實(shí)掌握MappedByteBuffer并不難,只要記住“三方三法三特性”(我自己總結(jié)的,呵呵~~不要扔雞蛋哦。。。)這句話就可以輕松搞定!MappedByteBuffer 只是一種特殊的 ByteBuffer ,即是ByteBuffer的子類。 MappedByteBuffer 將文件直接映射到內(nèi)存(這里的內(nèi)存指的是虛擬內(nèi)存,并不是物理內(nèi)存,后面說證明這一點(diǎn))。通常,可以映射整個文件,如果文件比較大的話可以分段進(jìn)行映射,只要指定文件的那個部分就可以。而且,與ByteBuffer十分類似,沒有構(gòu)造函數(shù)(你不可new MappedByteBuffer()來構(gòu)造一個MappedByteBuffer),我們可以通過 java.nio.channels.FileChannel 的 map() 方法來獲取 MappedByteBuffer 。其實(shí)說的通俗一點(diǎn)就是Map把文件的內(nèi)容被映像到計算機(jī)虛擬內(nèi)存的一塊區(qū)域,這樣就可以直接操作內(nèi)存當(dāng)中的數(shù)據(jù)而無需操作的時候每次都通過I/O去物理硬盤讀取文件,所以效率上有很大的提升!
三種方式:
???????FileChannel提供了map方法來把文件影射為內(nèi)存映像文件: MappedByteBuffer map(int mode,long position,long size); 可以把文件的從position開始的size大小的區(qū)域映射為內(nèi)存映像文件,mode指出了可訪問該內(nèi)存映像文件的方式:READ_ONLY,READ_WRITE,PRIVATE.?????????????????????
a. READ_ONLY,(只讀): 試圖修改得到的緩沖區(qū)將導(dǎo)致拋出 ReadOnlyBufferException.(MapMode.READ_ONLY)
?????? b. READ_WRITE(讀/寫): 對得到的緩沖區(qū)的更改最終將傳播到文件;該更改對映射到同一文件的其他程序不一定是可見的。 (MapMode.READ_WRITE)
?????? c. PRIVATE(專用):對得到的緩沖區(qū)的更改不會傳播到文件,并且該更改對映射到同一文件的其他程序也不是可見的;相反,會創(chuàng)建緩沖區(qū)已修改部分的專用副本。 (MapMode.PRIVATE)
三個方法:
a. fore();緩沖區(qū)是READ_WRITE模式下,此方法對緩沖區(qū)內(nèi)容的修改強(qiáng)行寫入文件
b. load()將緩沖區(qū)的內(nèi)容載入內(nèi)存,并返回該緩沖區(qū)的引用
c. isLoaded()如果緩沖區(qū)的內(nèi)容在物理內(nèi)存中,則返回真,否則返回假
import java.io.FileInputStream;import java.io.FileOutputStream;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;public class MapMemeryBuffer {public static void main(String[] args) throws Exception {ByteBuffer byteBuf = ByteBuffer.allocate(1024 * 14 * 1024);byte[] bbb = new byte[14 * 1024 * 1024];FileInputStream fis = new FileInputStream("d:\\test");FileOutputStream fos = new FileOutputStream("d:\\outFile.txt");FileChannel fc = fis.getChannel();long timeStar = System.currentTimeMillis();//得到當(dāng)前的時間fc.read(byteBuf);//1 讀取long timeEnd = System.currentTimeMillis();//得到當(dāng)前的時間System.out.println("Read time :" + (timeEnd - timeStar) + "ms");timeStar = System.currentTimeMillis();fos.write(bbb);// 寫入timeEnd = System.currentTimeMillis();System.out.println("Write time :" + (timeEnd - timeStar) + "ms");fos.flush();fc.close();fis.close();}}
三個特性:
調(diào)用信道的map()方法后,即可將文件的某一部分或全部映射到內(nèi)存中,映射內(nèi)存緩沖區(qū)是個直接緩沖區(qū),繼承自ByteBuffer,但相對于ByteBuffer,它有更多的優(yōu)點(diǎn):
a. 讀取快
b. 寫入快
c. 隨時隨地寫入
?????? 口說無憑,俗話說的好,是金子是銀子拿來煉一煉就知道(也不知道有沒有這么一句俗話,反正用到這還合適,就這么湊合吧,大家扔雞蛋~~~)!
1 MappedByteBuffer的讀取/寫入文件和普通I/O流的對比
?
輸出結(jié)果:
Read time :1874ms
Write time :360ms
把上面的程序的1換成MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fileLength);
2換成mbb.flip();
輸出結(jié)果:
Read ByteBuf take time :16ms
Write ByteBuf take time :0ms
可見普通I/O和MappedByteBuffer是沒法比的。另外在寫入的時候花了0ms說明Map寫入機(jī)制是根據(jù)你的更改量來決定,就是只保存修改部分的!
總結(jié)
以上是生活随笔為你收集整理的MappedByteBuffer的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: StarField模拟星空
- 下一篇: android中判断sim卡状态和读取联