1

During read ops i get java.io.IOException: Channel not open for writing - cannot extend file to required size

I have written simple program that reads file with MappedByteBuffer. The idea is to read file with regions according to API. But during execution i get exception. I have test file with the following content:

SimpleTestFile!

static void readFileWithChunks(final String file){

    final Path pathToFile = Paths.get(file);
    LOG.info("Path to file: {}", pathToFile.toString());

    try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(pathToFile, EnumSet.of(StandardOpenOption.READ))) {

        final long fileSize = fileChannel.size();
        LOG.info("Total size of the file: {} bytes", fileSize);

        final int maxChunkSize = 4;
        long startPosition = 0;
        long endPosition = 0;

        // main cycle to read chunks of data from file
        while (startPosition < fileSize){
            if (endPosition + maxChunkSize < fileSize){
                endPosition += maxChunkSize;
            } else {
                endPosition = fileSize;
            }
            readChunk(fileChannel, startPosition, endPosition);
            startPosition = endPosition;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}


static void readChunk(final FileChannel fileChannel, final long startPosition, final long endPosition) throws IOException {
    LOG.info("Start position: {}; End position: {}", startPosition, endPosition);

    final MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, startPosition, endPosition);

    final int bufferSize = (int) (endPosition - startPosition);
    LOG.info("Buffer size: {}", bufferSize);
    final byte[] buffer = new byte[bufferSize];

    mappedByteBuffer.get(buffer);

    LOG.info("Content of the buffer: {}", new String(buffer, StandardCharsets.UTF_8));
}

OUTPUT:

OUTPUT
21:39:39.192 [main] com.test.FileReader INFO - Path to file: /user/test/testfile.txt
21:39:39.196 [main] com.test.FileReader INFO - Total size of the file: 15 bytes
21:39:39.196 [main] com.test.FileReader INFO - Start position: 0; End position: 4
21:39:39.198 [main] com.test.FileReader INFO - Buffer size: 4
21:39:39.198 [main] com.test.FileReader INFO - Content of the buffer: Simp
21:39:39.198 [main] com.test.FileReader INFO - Start position: 4; End position: 8
21:39:39.198 [main] com.test.FileReader INFO - Buffer size: 4
21:39:39.198 [main] com.test.FileReader INFO - Content of the buffer: leTe
21:39:39.198 [main] com.test.FileReader INFO - Start position: 8; End position: 12
java.io.IOException: Channel not open for writing - cannot extend file to required size
    at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:901)
    at com.test.FileReader.readChunk(FileReader.java:59)
    at com.test.FileReader.readFile(FileReader.java:42)
    at com.test.TestClass.main(TestClass.java:14)
jspens
  • 11
  • 1
  • Problem still have no solution. If i change to WRITE mode its adding tailing zeroes to the file. – jspens Sep 12 '19 at 15:49

1 Answers1

0

Here's your issue:

final MappedByteBuffer mappedByteBuffer = 
    fileChannel.map(
        FileChannel.MapMode.READ_ONLY,
        startPosition,
        endPosition // <-- (endPosition - startPosition)
    );

FileChannel.map takes an offset + length, not a start + end:

public abstract MappedByteBuffer map(MapMode mode,
                                     long position, long size)
    throws IOException;

When you advance the mapped view beyond the file length, the underlying file is extended to accommodate (with undefined content between the previous end of the file and the new one). Extending the file requires write access, hence the exception.

JvR
  • 1,187
  • 8
  • 8