Read a file line by line in reverse order in Java
We will write a java program that reads a file line by line in reverse order i.e., from end to start.

In this post, we will go over below steps to write a Java program to read a file line by line in reverse order.
- We write Java code that reads the file from end to start.
- We will read the velocitybytes.log file which has some data.
- We will test the code that we have written.
Java Code:
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ReverseLineReader {
private static final int BUFFER_SIZE = 8192;
private final FileChannel channel;
private final String encoding;
private long filePos;
private ByteBuffer buffer;
private int bufferPos;
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private final RandomAccessFile raf;
// private final byte lastLineBreak = '\n';
public ReverseLineReader(File file) throws IOException {
this(file, null);
}
public ReverseLineReader(File file, String encoding) throws IOException {
raf = new RandomAccessFile(file, "r");
channel = raf.getChannel();
filePos = raf.length();
this.encoding = encoding;
}
public void close() throws IOException {
raf.close();
}
public String readLine() throws IOException {
byte c;
while (true) {
if (bufferPos < 0) {
if (filePos == 0) {
if (byteArrayOutputStream == null) {
return null;
}
String line = bufferToString();
byteArrayOutputStream = null;
return line;
}
long start = Math.max(filePos - BUFFER_SIZE, 0);
long end = filePos;
long len = end - start;
buffer = channel.map(FileChannel.MapMode.READ_ONLY, start, len);
bufferPos = (int) len;
filePos = start;
// Ignore Empty New Lines
c = buffer.get(--bufferPos);
if (c == '\r' || c == '\n')
while (bufferPos > 0 && (c == '\r' || c == '\n')) {
bufferPos--;
c = buffer.get(bufferPos);
}
if (!(c == '\r' || c == '\n'))
bufferPos++;// IS THE NEW LINE
}
/*
* This will ignore all blank new lines.
*/
while (bufferPos-- > 0) {
c = buffer.get(bufferPos);
if (c == '\r' || c == '\n') {
// skip \r\n
while (bufferPos > 0 && (c == '\r' || c == '\n')) {
c = buffer.get(--bufferPos);
}
// restore cursor
if (!(c == '\r' || c == '\n'))
bufferPos++;// IS THE NEW Line
return bufferToString();
}
byteArrayOutputStream.write(c);
}
/*
* If you don't want to ignore new line and would like
* to print new line too then use below code
* and comment out above while loop
while (bufPos-- > 0) {
byte c1 = buf.get(bufPos);
if (c1 == '\r' || c1 == '\n') {
if (c1 != lastLineBreak) {
lastLineBreak = c1;
continue;
}
lastLineBreak = c1;
return bufToString();
}
byteArrayOutputStream.write(c1);
}
*/
}
}
private String bufferToString() throws UnsupportedEncodingException {
if (byteArrayOutputStream.size() == 0) {
return "";
}
byte[] bytes = byteArrayOutputStream.toByteArray();
for (int i = 0; i < bytes.length / 2; i++) {
byte t = bytes[i];
bytes[i] = bytes[bytes.length - i - 1];
bytes[bytes.length - i - 1] = t;
}
byteArrayOutputStream.reset();
if (encoding != null)
return new String(bytes, encoding);
else
return new String(bytes);
}
}
Read a file:
Create a file (.txt or .log etc.,) that has some data.
// velocitybytes.log
Velocity Bytes
Java
Spring
React
Let's test:
import java.io.File;
import java.io.IOException;
public class ReverseLineReaderMain {
public static void main(String[] args) {
try {
File file = new File("C:\\velocitybytes.log");
ReverseLineReader reverseLineReader = new ReverseLineReader(file, "UTF-8");
String line;
while ((line = reverseLineReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
As expected, the following is the output:
React
Spring
Java
Velocity Bytes
Thanks for coming!