MappedByteBuffer--FileChannel--RandomAccessFile

內存映射文件

內存映射文件能讓你建立和修改那些由於太大而沒法放入內存的文件。有了內存映射文件,你就能夠認爲文件已經所有讀進了內存,而後把它當成一個很是大的數組來訪問。這種解決辦法能大大簡化修改文件的代碼。
fileChannel.map(FileChannel.MapMode mode, long position, long size)將此通道的文件區域直接映射到內存中。注意,你必須指明,它是從文件的哪一個位置開始映射的,映射的範圍又有多大;也就是說,它還能夠映射一個大文件的某個小片段。
java


MappedByteBuffer是ByteBuffer的子類,所以它具有了 ByteBuffer的全部方法,但新添了force()將緩衝區的內容強制刷新到存儲設備中去、load()將存儲設備中的數據加載到內存中、 isLoaded()位置內存中的數據是否與存儲設置上同步。這裏只簡單地演示了一下put()和get()方法,除此以外,你還可使用 asCharBuffer( )之類的方法獲得相應基本類型數據的緩衝視圖後,能夠方便的讀寫基本類型數據。
數組

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;app

public class LargeMappedFiles {
 static int length = 0x8000000; // 128 Mbdom

 public static void main(String[] args) throws Exception {
  // 爲了以可讀可寫的方式打開文件,這裏使用RandomAccessFile來建立文件。
  FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();
  // 注意,文件通道的可讀可寫要創建在文件流自己可讀寫的基礎之上
  MappedByteBuffer out = fc
    .map(FileChannel.MapMode.READ_WRITE, 0, length);
  // 寫128M的內容
  for (int i = 0; i < length; i++) {
   out.put((byte) 'x');
  }
  System.out.println("Finished writing");
  // 讀取文件中間6個字節內容
  for (int i = length / 2; i < length / 2 + 6; i++) {
   System.out.print((char) out.get(i));
  }
  fc.close();
 }
}性能

Finished writing
xxxxxxspa

儘管映射寫彷佛要用到FileOutputStream,可是映射文件中的全部輸出 必須使用RandomAccessFile,但若是隻須要讀時可使用FileInputStream,寫映射文件時必定要使用隨機訪問文件,可能寫時要讀的緣由吧。操作系統

 

該程序建立了一個128Mb的文件,若是一次性讀到內存可能致使內存溢出,但這裏訪問好像只是一瞬間的事,這是由於,真正調入內存的只是其中的一小部分,其他部分則被放在交換文件上。這樣你就能夠很方便地修改超大型的文件了(最大能夠到2 GB)。注意,Java是調用操做系統的"文件映射機制"來提高性能的。內存

本站公眾號
   歡迎關注本站公眾號,獲取更多信息