Reading the Last Line of a Text File Efficiently with Java
Reading the last line of a large text file efficiently is a common challenge in Java programming. The standard method of reading the file line by line is not efficient, as it requires iterating through the entire file.
A more efficient approach is to use the RandomAccessFile class. This class allows random access to a file, enabling us to directly access the last line without stepping through the entire file. The following code demonstrates this approach:
public String tail(File file) { RandomAccessFile fileHandler = null; try { fileHandler = new RandomAccessFile(file, "r"); long fileLength = fileHandler.length() - 1; StringBuilder sb = new StringBuilder(); // Start from the last character of the file for (long filePointer = fileLength; filePointer != -1; filePointer--) { fileHandler.seek(filePointer); int readByte = fileHandler.readByte(); // Check for line break if (readByte == 0xA) { if (filePointer == fileLength) { continue; } break; } else if (readByte == 0xD) { if (filePointer == fileLength - 1) { continue; } break; } // Append character to the string builder sb.append((char) readByte); } String lastLine = sb.reverse().toString(); return lastLine; } catch (java.io.FileNotFoundException e) { e.printStackTrace(); return null; } catch (java.io.IOException e) { e.printStackTrace(); return null; } finally { if (fileHandler != null) { try { fileHandler.close(); } catch (IOException e) { /* ignore */ } } } }
This method efficiently returns the last line of the file without loading or stepping through the entire file.
However, in many scenarios, you may need to read the last N lines of the file. The following code demonstrates a method that can achieve this:
public String tail2(File file, int lines) { RandomAccessFile fileHandler = null; try { fileHandler = new java.io.RandomAccessFile(file, "r"); long fileLength = fileHandler.length() - 1; StringBuilder sb = new StringBuilder(); int line = 0; // Start from the last character of the file for (long filePointer = fileLength; filePointer != -1; filePointer--) { fileHandler.seek(filePointer); int readByte = fileHandler.readByte(); // Check for line break if (readByte == 0xA) { if (filePointer < fileLength) { line = line + 1; } } else if (readByte == 0xD) { if (filePointer < fileLength - 1) { line = line + 1; } } // Break if the required number of lines have been reached if (line >= lines) { break; } // Append character to the string builder sb.append((char) readByte); } String lastLine = sb.reverse().toString(); return lastLine; } catch (java.io.FileNotFoundException e) { e.printStackTrace(); return null; } catch (java.io.IOException e) { e.printStackTrace(); return null; } finally { if (fileHandler != null) { try { fileHandler.close(); } catch (IOException e) { } } } }
This method similarly uses the RandomAccessFile class to efficiently read the last N lines of the file.
These methods can be invoked as follows:
File file = new File("D:\stuff\huge.log"); System.out.println(tail(file)); System.out.println(tail2(file, 10));
Note: These methods may not produce Unicode characters correctly due to reversal, so it is important to test thoroughly with different languages.
The above is the detailed content of How to efficiently read the last line of a text file in Java?. For more information, please follow other related articles on the PHP Chinese website!