2012-02-03 88 views
2

我知道如何創建一個內存映射文件,但我的問題是,我們說的是,在下面一行:內存映射文件的Java NIO

FileChannel roChannel = new RandomAccessFile(file, "r").getChannel(); 
ByteBuffer roBuf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, SIZE); 

如果我設置大小爲例如2MB,做到這一點的手段它只會加載2MB的文件,還是會在文件中進一步讀取,並更新緩衝區,因爲我從中消耗了字節?

+5

只有映射的部分可以通過該緩衝區訪問。把它想象成整個文件的一個窗口,只有可見區域可以被讀取(寫入) – bestsss 2012-02-03 01:33:13

+0

@bestsss:你應該把它作爲一個答案來代替。 – Jonas 2012-02-03 01:39:34

+0

@Jonas,...不喜歡單個句子中的答案。答案也很明顯。提問者總是可以自己回覆並選擇它。 – bestsss 2012-02-03 01:56:56

回答

2

緩衝區的大小是您傳入的大小,它不會增長或縮小。

javadoc說:

地圖上的這個通道的文件區域直接到內存中。

...

尺寸 - 該區域的大小要被映射;必須爲非負且不大於Integer.MAX_VALUE的

編輯更大:

根據你所說的什麼「更新了新的數據」,答案是肯定的。

通過這個類的一個實例提供的文件的視圖保證與由在同一程序中其他實例提供同一文件的其它視圖相一致。然而,由這個類的一個實例提供的視圖可能會或可能不會與由其他併發運行的程序看到的視圖一致,這是由於底層操作系統執行的緩存和網絡文件系統協議引起的延遲。無論編寫這些其他程序的語言如何,以及它們是在同一臺機器上還是在其他某臺機器上運行,情況都是如此。任何此類不一致的確切性質都與系統有關,因此未予指明。

,因此,其他系統可能會做緩存,但是當這些高速緩存清空或以其他方式跟上時代的,他們將與由FileChannel提出的觀點。

您還可以使用顯式調用position方法和其他方法來更改視圖呈現的內容。

更改通道的位置,無論是顯式讀取還是通過讀取或寫入字節,都會更改原始對象的文件位置,反之亦然。通過文件通道更改文件的長度將改變通過原始對象看到的長度,反之亦然。通過寫入字節來更改文件的內容將改變原始對象看到的內容,反之亦然。

+0

我知道緩衝區不會增長,我的問題是當我消耗的時候它是否會隨新數據更新,javadoc在這方面並不十分清楚。 – raygozag 2012-02-04 04:57:34

+0

@raygozag,請參閱我的編輯。 – 2012-02-04 13:59:24

4

其中i集合大小是例如2MB,這是否意味着它將只有文件的負載2MB或將它進一步在該文件中讀出並作爲我消耗從它的字節更新緩衝器?

它只會加載緩衝區初始化中指定的文件部分。如果你想要進一步閱讀,你需要有一些閱讀循環。雖然我不會說這很棘手,但如果不是100%熟悉所涉及的java.io和java.nio API,那麼填充它的可能性很高。 (例如。:不翻轉緩衝區;緩衝區/文件邊緣案例錯誤)。

如果您正在尋找一種在ByteBuffer中訪問此文件的簡單方法,請考慮使用MappedByteBuffer

RandomAccessFile raf = new RandomAccessFile(file, "r"); 
FileChannel fc = raf.getChannel(); 
MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 

的妙處在這種情況下使用MBB一個是,它不一定會實際上整個緩衝區加載到內存中,而是隻有你訪問的部分。