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

Comments

Subscribe
Notify of
guest
14 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.