Reading a File with Channels and Buffers

Learn to read small and large files from the filesystem using the Java NIO APIs Path, FileChannel, ByteBuffer and MappedByteBuffer.

  • We are using the RandomAccessFile instance that behaves like a large array of bytes stored in the file system. It uses file pointers that act as a cursor to maintain the current read location in the file.
  • A ByteBuffer represents the buffered bytes in the memory during the read/write operations.
  • A MappedByteBuffer is a direct byte buffer whose content is a memory-mapped region of a file.

1. Reading Small Files with ByteBuffer and FileChannel

Use this technique to read a small file. The idea is to create a ByteBuffer large enough where all the file content fits into the buffer, and the file can be read in a single read() operation.

try(RandomAccessFile aFile = new RandomAccessFile("test.txt", "r");
  FileChannel inChannel = aFile.getChannel();) {
  
  long fileSize = inChannel.size();

  //Create buffer of the file size
  ByteBuffer buffer = ByteBuffer.allocate((int) fileSize);
  inChannel.read(buffer);
  buffer.flip();

  // Verify the file content
  for (int i = 0; i < fileSize; i++) {
    System.out.print((char) buffer.get());
  }
} catch (IOException e) {
  e.printStackTrace();
}

2. Reading Large Files with ByteBuffer and FileChannel

Use this technique to read a large file where all the file content will not fit into the buffer at a time. To avoid OutOfMemory issues, we can read the file in chunks with a fixed size small buffer.

try (RandomAccessFile aFile = new RandomAccessFile("test.txt", "r");
  FileChannel inChannel = aFile.getChannel();) {

  //Buffer size is 1024
  ByteBuffer buffer = ByteBuffer.allocate(1024);

  while (inChannel.read(buffer) > 0) {
    buffer.flip();
    for (int i = 0; i < buffer.limit(); i++) {
      System.out.print((char) buffer.get());
    }
    buffer.clear(); // do something with the data and clear/compact it.
  }
} catch (IOException e) {
  e.printStackTrace();
}

3. Reading a File using MappedByteBuffer

MappedByteBuffer extends the ByteBuffer class with operations that are specific to memory-mapped file regions.

try (RandomAccessFile aFile = new RandomAccessFile("test.txt", "r");
  FileChannel inChannel = aFile.getChannel();) {

  MappedByteBuffer buffer = inChannel
    .map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());

  buffer.load();
  for (int i = 0; i < buffer.limit(); i++) {
    System.out.print((char) buffer.get());
  }
  buffer.clear(); // do something with the data and clear/compact it.

} catch (IOException e) {
  e.printStackTrace();
}

All the above techniques will read the content of the file and print it to the console.

Happy Learning !!

Source Code on Github

Leave a Reply

15 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.

Our Blogs

REST API Tutorial