Search code examples
javaniomemory-mapped-filesnio2

Reusing MemoryMappedByteBuffer


I read a file into a MappedByteBuffer:

MappedByteBuffer buffer = FileChannel.open(file, StandardOpenOption.READ)
    .map(FileChannel.MapMode.READ_ONLY, 0, Files.size(file))
    .load();

And write it to an OutputStream:

Channels.newChannel(getOutputStream())
    .write(buffer);

However, I can only do this one, presumably because the ByteBuffer "current location" is at the end of the buffer.

So what is the recommended way to handle the fact I wish to have multiple threads use this memory mapped file?


Solution

  • Use rewind():

    Rewinds this buffer. The position is set to zero and the mark is discarded.

    Invoke this method before a sequence of channel-write or get operations, assuming that the limit has already been set appropriately.

    Channels.newChannel(getOutputStream()).write(buffer);
    buffer.rewind();
    // ...
    Channels.newChannel(getOutputStream()).write(buffer);
    buffer.rewind();
    // ...
    

    Please note that ByteBuffer is not a thread-safe structure.

    You best option is probably to make a copy of the ByteBuffer for each thread so that it can be read concurrently:

    // in thread 1
    ByteBuffer duplicate = buffer.duplicate();
    // ...
    // in thread 2
    ByteBuffer duplicate = buffer.duplicate();
    // ...