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 !!