How do I read last n characters from a file?

In the following post you will learn how to read last n characters from a file. The JDK 7 introduces a new SeekableByteChannel interface which allows its implementation to change the position and the size of the byte channel. One of its implementation is the FileChannel class (java.nio.channels.FileChannel).

The FileChannel class make it possible to get hold the current position of where we are going to read from or write to a file. The code snippet below shows you how you can read the last 1000 characters from a log file.

package org.kodejava.io;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class FileReadLastNCharacters {
    public static void main(String[] args) {
        // Defines the path to the log file and creates a ByteBuffer.
        Path logPath = Paths.get("C:/tools/apache-tomcat-10.0.11/logs/catalina.out");
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        try {
            // Creates FileChannel and open the file channel for read access.
            FileChannel channel = FileChannel.open(logPath, StandardOpenOption.READ);

            // Read a sequence of bytes from the channel into the buffer starting
            // at given file position, which is the channel size - 1000. Because
            // we are going to read the last 1000 characters from the file.
            channel.read(buffer, channel.size() - 1000);
            System.out.println("Characters = " + new String(buffer.array()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The steps in the code snippet above are:

  • Get the path to the log file.
  • Create a ByteBuffer, a buffer where the read bytes to be transferred.
  • Using the FileChannel.open() method we open a file to be read and return a FileChannel object.
  • The read() method of the FileChannel reads a sequence of bytes from the channel and transfer them to the given buffer starting and the position defined by channel.size() - 1000. This method returns the number of bytes read, possible zero, or -1 if the given position is greater than or equal to the file’s current size.
  • Print out the buffered string.