How comes .array() doesn't work on ByteBuffers returned from map'ed FileChannels?

bytebuffer, java, memory-mapping

Solution

I'm going to assume this is about the `FileChannel.map` method which can map a file to memory which can be accessed by a `MappedByteBuffer`.

In the documentation for the `FileChannel.map` method, if the file is mapped as read-only, the any attempt to modify the buffer will result in a `ReadOnlyBufferException`:

A region of a file may be mapped into memory in one of three modes:

- Read-only: Any attempt to modify the resulting buffer will cause a `ReadOnlyBufferException` to be thrown. (`MapMode.READ_ONLY`)

In terms of the exceptions thrown by the `ByteBuffer.array` method, there are two types of exceptions which are thrown depending on the reason for the problem:

Throws:

- `ReadOnlyBufferException` - If this buffer is backed by an array but is read-only

- `UnsupportedOperationException` - If this buffer is not backed by an accessible array

Although the exception being thrown is not mentioned in the question, perhaps the file being read-only is causing the `ReadOnlyBufferException` to be thrown by the `array` method.

Also, it should also be mentioned that the `ByteBuffer.array` method is an optional operation:

Returns the byte array that backs this buffer (optional operation).

To be sure that the `array` method will return a `byte[]` that can be used, invoke the `hasArray` method as suggested in the documentation for the `array` method:

Invoke the `hasArray` method before invoking this method in order to ensure that this buffer has an accessible backing array.

Problem

I'm doing memory-mapped IO in Java. The FileChannel class allows you to map a ByteBuffer to a particular part of a file. I'm doing that with a file opened read only. The problem I am having is that I'm getting an exception when I attempt to call the .array() method on the resulting ByteBuffer. Perhaps that's because the .array() returns a byte[] array, and I really want a finalized byte array? Is there any way around this?

Original source