Search code examples
javaasynchronousfilechanneljava.nio.file

MappedByteBuffer throwing a java.nio.BufferOverflowException


I am learning java nio and I am using MappedByteBuffer and ExecutorService to copy files asynchronously. My problem is the method MappedByteBuffer.put() is throwing java.nio.BufferOverflowException. But in my debug I am not copying to over position on my target file. This is the part of the code that I use to create the new copy of the file:

for (Future<?> f : futures) {
                Message message = (Message) f.get();
                try (FileChannel fileChannel = (FileChannel) Files
                        .newByteChannel(pathWrite, EnumSet.of(
                                StandardOpenOption.READ,
                                StandardOpenOption.WRITE,
                                StandardOpenOption.TRUNCATE_EXISTING))) {
                    MappedByteBuffer mbb = fileChannel.map(
                            FileChannel.MapMode.READ_WRITE, message.getCod(),
                            message.getValue());

                    if (mbb != null) {
                        System.out.println("start: " + message.getCod()
                                + " - end: " + message.getValue());
                        ByteBuffer encode = Charset.forName(charEncoding)
                                .encode(message.getCharBuffer());
                        mbb.put(encode); // here
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

and the exception is :

java.nio.BufferOverflowException
    at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:363)
    at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:342)
    at memo.MultiThreadingMappedByteBufferExample.multiThreadedWayWithExecutorService(MultiThreadingMappedByteBufferExample.java:139)

Solution

  • You're truncating the file to zero length, mapping some unknown part of it according to the offset and length values provided by message.getCod() and message.getValue(), which doesn't exist because the file is zero length, and then trying to put the charBuffer provided with the message into the file, which is still zero length, at the offset defined by message.getCod(), which doesn't exist, so you get a BufferOverflowException.

    I suggest you don't truncate the file to start with, but it isn't clear why any of this should work. I suggest you use a RandomAccessFile. Simpler. You shouldn't use lots of memory-mapped files in a single application, and using it just for this tiny job is inappropriate.