Java.NIO InvalidIndexException-如何随机访问大文件进行读写

Java.NIO InvalidIndexException-如何随机访问大文件进行读写,java,nio,Java,Nio,我已经围绕java.io.RandomAccessFile(一个只有54 KB大小的文件)创建了一个java.nio.MappedByteBuffer。生成的MappedByteBuffer的“容量”和“限制”大约为12KB,因此当我尝试调用mybytebuffer.get(I>13044)或mybytebuffer.put(I>13044,value)时,它会抛出一个invalidIndexception 所有这些行为都记录在Sun的官方javadocs中。我的问题是如何使用java.nio

我已经围绕
java.io.RandomAccessFile
(一个只有54 KB大小的文件)创建了一个
java.nio.MappedByteBuffer
。生成的
MappedByteBuffer
的“容量”和“限制”大约为12KB,因此当我尝试调用
mybytebuffer.get(I>13044)
mybytebuffer.put(I>13044,value)
时,它会抛出一个
invalidIndexception


所有这些行为都记录在Sun的官方javadocs中。我的问题是如何使用
java.nio ByteBuffers
读取或写入文件中的任意位置(我需要随机访问)。我似乎找不到说明非顺序访问的Java NIO示例或文档。

MappedBytebuffer本身不提供随机访问。这是一种误解。使用seekablebytechnel进行随机访问。

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和访问字节(读写)。

是否尝试调用限制(实际大小)?是的,但我无法设置限制>容量。容量是一个无法增加的硬限制。我希望我可以隐藏这样一个事实,即ByteBuffer被包装在使用它的代码的文件中,但现在对我来说,这似乎是不可能的:没有本机解决方案,您不能扩展ByteBuffer来生成自己的抽象。难看。为什么要为54KB的文件使用内存映射文件呢?内存映射对于大型文件有其优势。对于小文件,由于映射的初始化需要一些时间,它通常比较慢。54KB的文件只是对我的代码的测试。+1。只要file.length()小于Integer.MAX_INT,它就可以工作。使用此函数,我似乎得到了一个不可写的通道异常;我会调查的。如果你使用FileInputStream,这个频道是不可写的。如果使用FileOutputStream,则通道不可读。使用RandomAccessFile生成一个可读写的频道。@Jason Knight:很好,我修改了答案。(每天学习新东西!)FileChannel(在选定答案中建议)是SeekableByteChannel的唯一实现类: