2010-01-09 52 views
1

我創建了一個圍繞java.io.RandomAccessFile(文件大小僅爲54 KB)的java.nio.MappedByteBuffer。由此產生的MappedByteBuffer的「容量」和「限制」大約爲12 KB,因此當我嘗試調用mybytebuffer.get(i > 13044)mybytebuffer.put(i > 13044, value)時,它會拋出InvalidIndexExceptionJava.NIO InvalidIndexException - 如何隨機訪問大文件進行讀寫操作

所有這些行爲都記錄在Sun的官方javadoc中。我的問題是我如何使用java.nio ByteBuffers來讀取或寫入文件中的任何地方(我需要隨機訪問)。我似乎無法找到說明非順序訪問的Java NIO的示例或文檔。

+0

您是否嘗試過調用限制(實際大小)? – bmargulies 2010-01-09 02:57:48

+0

是的,但我不能設置限制>容量。容量是一個不能提高的硬限制。我希望能夠隱藏一個事實,即ByteBuffer將文件包裝到使用它的代碼中,但現在對我來說似乎是不可能的:沒有本地解決方案,並且無法擴展ByteBuffer以進行自己的抽象。 醜。 – 2010-01-09 03:11:33

+1

爲什麼還要爲54KB文件使用內存映射文件?內存映射對於大文件有其優勢。對於小文件,由於映射的初始化需要一些時間,所以它通常比較慢。 – dmeister 2010-01-09 13:58:23

回答

1

MappedByteBuffer可以隨機訪問文件......它是一個'直接字節緩衝區'。 (具體地講,它使用操作系統的虛擬內存子系統,將文件映射到內存中。)

您可以隨機訪問字節的代碼片段在這裏:

public void doIt() throws FileNotFoundException, IOException { 
    File file = new File("myfile"); 
    RandomAccessFile raf = new RandomAccessFile(file, "rw"); 
    FileChannel fc = raf.getChannel();  
    MappedByteBuffer mbb = fc.map(MapMode.READ_WRITE, 0, file.length()); 

    //get a random byte 
    byte b1 = mbb.get(SOME_RANDOM_BYTE); 

    //get another random byte 
    mbb.position(SOME_OTHER_BYTE_POSITION); 
    byte b2 = mbb.get(); 
} 

你可以走動的MBB和訪問字節(包括閱讀和寫作),只要你需要。

+0

+1。只要file.length()小於Integer.MAX_INT就行。 – dmeister 2010-01-09 13:56:51

+0

我似乎得到一個NonWriteableChannelException使用此;我會研究它。 – 2010-01-09 23:27:39

+0

如果使用FileInputStream,則通道不可寫入。如果您使用FileOutputStream,則該通道不可讀。使用RandomAccessFile生成可讀寫的通道。 – 2010-01-10 05:50:27

0

MappedByteBuffers本身並不提供隨機訪問。這是一個誤解。使用SeekableByteChannel進行隨機訪問。

相關問題