0

I am trying to read last n lines of a file in reverse order. Is this the most efficient way to do it? My file is not big but it could eventually grow to several GB. Also, I am trying to read last 10 lines but this one only returns last 9. Anything I am missing?

// Read n lines from the end of the file
public void readFromLast(File file, int lines) {
    int readLines = 0;
    StringBuilder builder = new StringBuilder();
    RandomAccessFile randomAccessFile = null;
    try {
        randomAccessFile = new RandomAccessFile(file, "r");
        long fileLength = file.length() - 1;
        // Set the pointer at the last of the file
        randomAccessFile.seek(fileLength);
        for (long pointer = fileLength; pointer >= 0; pointer--) {
            randomAccessFile.seek(pointer);
            char c = (char) randomAccessFile.read();
            builder.append(c);
            if(c == '\n'){
                builder = builder.reverse();
                System.out.print(builder.toString());
                readLines++;
                builder = null;
                builder = new StringBuilder();
                if (readLines == lines + 1){
                    break;
                }
            }
        }
    } catch (FileNotFoundException e) {
        log.info("FileNotFound " +e.getMessage()+ "occured while reading last n lines");
        e.printStackTrace();
    } catch (IOException e) {
        log.info("IOException" + e.getMessage() +" occured while reading last n lines");
    } finally {
        if (randomAccessFile != null) {
            try {
                randomAccessFile.close();
            } catch (IOException e) {
                log.info("IOException" + e.getMessage() +" occured while closing the file reading last n lines");
            }
        }
    }
}
rickygrimes
  • 2,637
  • 9
  • 46
  • 69
  • 1
    Look at the contents of the first line that your program prints. If that doesn't answer your question, step through your program with the debugger. (you can pass 1 for `lines` to make it easier to see what's happening) – tgdavies Nov 22 '21 at 01:00
  • If the last line ends with `\n` then you get 9. You should handle both: last byte LF or not. – Joop Eggen Nov 22 '21 at 01:34
  • Anything known about the character encoding? – meriton Nov 22 '21 at 01:44
  • See [How to read file from end to start (in reverse order) in Java? - Stack Overflow](https://stackoverflow.com/questions/8664705/how-to-read-file-from-end-to-start-in-reverse-order-in-java). –  Nov 22 '21 at 03:51

1 Answers1

0

Your code is fine. I am pretty sure it is reading 1 more line than it should, not 1 less. You are probably reading file that does not have enough lines?

If you want to correct it remove +1 from if (readLines == lines + 1){ and it will be fine.

Also a tip instead of setting StringBuilder to null and creating it again you can use

bulder.setLength(0);

it is a bit cleaner

Vojin Purić
  • 2,140
  • 7
  • 9
  • 22