Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I had the same problem as described here. I want to look at lines in file in reverse order, from the end back to the start (The unix tac command will do it). </p> <p>However my input files are fairly large so reading the whole file into memory, as in the other examples was not really a workable option for me.</p> <p>Below is the class I came up with, it does use <code>RandomAccessFile</code>, but does not need any buffers, since it just retains pointers to the file itself, and works with the standard <code>InputStream</code> methods. </p> <p>It works for my cases, and empty files and a few other things I've tried. Now I don't have Unicode characters or anything fancy, but as long as the lines are delimited by LF, and even if they have a LF + CR it should work.</p> <p>Basic Usage is : </p> <pre><code>in = new BufferedReader (new InputStreamReader (new ReverseLineInputStream(file))); while(true) { String line = in.readLine(); if (line == null) { break; } System.out.println("X:" + line); } </code></pre> <p>Here is the main source: </p> <pre><code>package www.kosoft.util; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.RandomAccessFile; public class ReverseLineInputStream extends InputStream { RandomAccessFile in; long currentLineStart = -1; long currentLineEnd = -1; long currentPos = -1; long lastPosInFile = -1; public ReverseLineInputStream(File file) throws FileNotFoundException { in = new RandomAccessFile(file, "r"); currentLineStart = file.length(); currentLineEnd = file.length(); lastPosInFile = file.length() -1; currentPos = currentLineEnd; } public void findPrevLine() throws IOException { currentLineEnd = currentLineStart; // There are no more lines, since we are at the beginning of the file and no lines. if (currentLineEnd == 0) { currentLineEnd = -1; currentLineStart = -1; currentPos = -1; return; } long filePointer = currentLineStart -1; while ( true) { filePointer--; // we are at start of file so this is the first line in the file. if (filePointer &lt; 0) { break; } in.seek(filePointer); int readByte = in.readByte(); // We ignore last LF in file. search back to find the previous LF. if (readByte == 0xA &amp;&amp; filePointer != lastPosInFile ) { break; } } // we want to start at pointer +1 so we are after the LF we found or at 0 the start of the file. currentLineStart = filePointer + 1; currentPos = currentLineStart; } public int read() throws IOException { if (currentPos &lt; currentLineEnd ) { in.seek(currentPos++); int readByte = in.readByte(); return readByte; } else if (currentPos &lt; 0) { return -1; } else { findPrevLine(); return read(); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload