<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    咖啡伴侶

    呆在上海
    posts - 163, comments - 156, trackbacks - 0, articles - 2

    java nio 之MappedByteBuffer,高效文件/內存映射

    Posted on 2013-01-05 10:49 oathleo 閱讀(1131) 評論(0)  編輯  收藏 所屬分類: 自己
    MappedByteBuffer是java nio引入的文件內存映射方案,讀寫性能極高。NIO最主要的就是實現了對異步操作的支持。其中一種通過把一個套接字通道(SocketChannel)注冊到一個選擇器(Selector)中,不時調用后者的選擇(select)方法就能返回滿足的選擇鍵(SelectionKey),鍵中包含了SOCKET事件信息。這就是select模型。
        SocketChannel的讀寫是通過一個類叫ByteBuffer(java.nio.ByteBuffer)來操作的.這個類本身的設計是不錯的,比直接操作byte[]方便多了. ByteBuffer有兩種模式:直接/間接.間接模式最典型(也只有這么一種)的就是HeapByteBuffer,即操作堆內存 (byte[]).但是內存畢竟有限,如果我要發送一個1G的文件怎么辦?不可能真的去分配1G的內存.這時就必須使用"直接"模式,即 MappedByteBuffer,文件映射.
         先中斷一下,談談操作系統的內存管理.一般操作系統的內存分兩部分:物理內存;虛擬內存.虛擬內存一般使用的是頁面映像文件,即硬盤中的某個(某些)特殊的文件.操作系統負責頁面文件內容的讀寫,這個過程叫"頁面中斷/切換". MappedByteBuffer也是類似的,你可以把整個文件(不管文件有多大)看成是一個ByteBuffer.MappedByteBuffer 只是一種特殊的 ByteBuffer ,即是ByteBuffer的子類。 MappedByteBuffer 將文件直接映射到內存(這里的內存指的是虛擬內存,并不是物理內存)。通常,可以映射整個文件,如果文件比較大的話可以分段進行映射,只要指定文件的那個部分就可以。

    三種方式:
                  FileChannel提供了map方法來把文件影射為內存映像文件: MappedByteBuffer map(int mode,long position,long size); 可以把文件的從position開始的size大小的區域映射為內存映像文件,mode指出了 可訪問該內存映像文件的方式:READ_ONLY,READ_WRITE,PRIVATE.                     
    a. READ_ONLY,(只讀): 試圖修改得到的緩沖區將導致拋出 ReadOnlyBufferException.(MapMode.READ_ONLY)
     b. READ_WRITE(讀/寫): 對得到的緩沖區的更改最終將傳播到文件;該更改對映射到同一文件的其他程序不一定是可見的。 (MapMode.READ_WRITE)
    c. PRIVATE(專用): 對得到的緩沖區的更改不會傳播到文件,并且該更改對映射到同一文件的其他程序也不是可見的;相反,會創建緩沖區已修改部分的專用副本。 (MapMode.PRIVATE)

    三個方法:

    a. fore();緩沖區是READ_WRITE模式下,此方法對緩沖區內容的修改強行寫入文件
    b. load()將緩沖區的內容載入內存,并返回該緩沖區的引用
    c. isLoaded()如果緩沖區的內容在物理內存中,則返回真,否則返回假

    三個特性:

        調用信道的map()方法后,即可將文件的某一部分或全部映射到內存中,映射內存緩沖區是個直接緩沖區,繼承自ByteBuffer,但相對于ByteBuffer,它有更多的優點:

    a. 讀取快
    b. 寫入快
    c. 隨時隨地寫入

    下面來看代碼:

    package study;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.ByteBuffer;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;

    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("e://data/other/UltraEdit_17.00.0.1035_SC.exe");
            FileOutputStream fos = new FileOutputStream("e://data/other/outFile.txt");
            FileChannel fc = fis.getChannel();
            long timeStar = System.currentTimeMillis();// 得到當前的時間
            fc.read(byteBuf);// 1 讀取
            //MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
            System.out.println(fc.size()/1024);
            long timeEnd = System.currentTimeMillis();// 得到當前的時間
            System.out.println("Read time :" + (timeEnd - timeStar) + "ms");
            timeStar = System.currentTimeMillis();
            fos.write(bbb);//2.寫入
            //mbb.flip();
            timeEnd = System.currentTimeMillis();
            System.out.println("Write time :" + (timeEnd - timeStar) + "ms");
            fos.flush();
            fc.close();
            fis.close();
        }

    }

    運行結果:
    14235
    Read time :24ms
    Write time :21ms
    我們把標注1和2語句注釋掉,換成它們下面的被注釋的那條語句,再來看運行效果。
    14235
    Read time :2ms
    Write time :0ms
    可以看出速度有了很大的提升。MappedByteBuffer的確快,但也存在一些問題,主要就是內存占用和文件關閉等不確定問題。被MappedByteBuffer打開的文件只有在垃圾收集時才會被關閉,而這個點是不確定的。在javadoc里是這么說的:
    A mapped byte buffer and the file mapping that it represents remain valid until the buffer itself 
    is garbage-collected.

    這里提供一種解決方案:
    AccessController.doPrivileged(new PrivilegedAction() {
      public Object run() {
        try {
          Method getCleanerMethod = buffer.getClass().getMethod("cleaner", new Class[0]);
          getCleanerMethod.setAccessible(true);
          sun.misc.Cleaner cleaner = (sun.misc.Cleaner)
          getCleanerMethod.invoke(byteBuffer, new Object[0]);
          cleaner.clean();
        } catch (Exception e) {
          e.printStackTrace();
        }
        return null;
      }
    });

    主站蜘蛛池模板: 九九免费观看全部免费视频| 国产成人亚洲毛片| 久久国产精品免费看| 久久久久亚洲精品男人的天堂| 国产精品免费久久久久影院 | 1a级毛片免费观看| 久久久久亚洲精品影视| 国产午夜亚洲精品不卡| 国产精品亚洲AV三区| 永久免费观看的毛片的网站| 国产成人亚洲综合一区| 日韩免费一级毛片| 黄色一级毛片免费| 亚洲国产另类久久久精品小说| 国产精成人品日日拍夜夜免费| 亚洲国产精品久久66| 一个人免费观看www视频在线| 亚洲午夜福利在线视频| 亚洲国产精品人人做人人爱| 四虎国产精品免费永久在线| 日韩亚洲Av人人夜夜澡人人爽| 一二三四在线播放免费观看中文版视频 | 亚洲剧情在线观看| 在线免费观看一级毛片| 一级毛片高清免费播放| 亚洲国语精品自产拍在线观看| 亚洲免费在线视频播放| 亚洲国产精品网站在线播放 | 一级人做人爰a全过程免费视频| 亚洲区小说区图片区QVOD| 桃子视频在线观看高清免费视频| 亚洲乱码无限2021芒果| 免费人妻av无码专区| 无码专区AAAAAA免费视频| 色偷偷女男人的天堂亚洲网 | 亚洲第一页综合图片自拍| 免费人妻无码不卡中文字幕系| 97久久国产亚洲精品超碰热| yy6080亚洲一级理论| 亚洲免费黄色网址| 一级全免费视频播放|