Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In this post I'll provide you with two completely different approaches to solving your problem, and depending on your use case one of the solutions will fit better than the other.</p> <p><strong>Alternative #1</strong></p> <p>This method is memory efficient though quite complex, if you are going to skip a lot of contents this method is recommended since you only will store one line at a time in memory during processing.</p> <p>The implementation of it in this post might not be <strong>super</strong> optimized, but the theory behind it stands clear.</p> <p>You will start by reading the file backwards, searching for N number of line breaks. When you've successfully located where in the file you'd like to stop your processing later on you will jump back to the beginning of the file.</p> <p><strong>Alternative #2</strong></p> <p>This method is easy to comprehend and is very straight forward. During execution you will have N number of lines stored in memory, where N is the number of lines you'd like to skip in the end.</p> <p>The lines will be stored in a FIFO container (<em>First In, First Out</em>). You'll append the last read line to your FIFO and then remove and process the first entry. This way you will always process lines at least N entries away from the end of your file.</p> <hr> <hr> <h1>Alternative #1</h1> <p>This might sound odd but it's definitely doable and the way I'd recommend you to do it; start by reading the file <strong>backwards</strong>.</p> <ol> <li>Seek to the end of the file</li> <li>Read (and discard) bytes (towards the beginning of the file) until you've found <code>SKIP_N</code> line breaks</li> <li>Save this position</li> <li>Seek to the beginning of the file</li> <li>Read (and process) lines until you've come down to the position you've stored away</li> </ol> <hr> <h2>Example code:</h2> <p>The code below will strip off the last <code>42</code> lines from <code>/tmp/sample_file</code> and print the rest using the method described earlier in this post.</p> <pre><code>import java.io.RandomAccessFile; import java.io.File; import java.lang.Math; public class Example { protected static final int SKIP_N = 42; public static void main (String[] args) throws Exception { File fileHandle = new File ("/tmp/sample_file"); RandomAccessFile rafHandle = new RandomAccessFile (fileHandle, "r"); String s1 = new String (); long currentOffset = 0; long endOffset = findEndOffset (SKIP_N, rafHandle); rafHandle.seek (0); while ((s1 = rafHandle.readLine ()) != null) { ; currentOffset += s1.length () + 1; // (s1 + "\n").length if (currentOffset &gt;= endOffset) break; System.out.println (s1); } } protected static long findEndOffset (int skipNLines, RandomAccessFile rafHandle) throws Exception { long currentOffset = rafHandle.length (); long endOffset = 0; int foundLines = 0; byte [] buffer = new byte[ 1024 &gt; rafHandle.length () ? (int) rafHandle.length () : 1024 ]; while (foundLines &lt; skipNLines &amp;&amp; currentOffset != 0) { currentOffset = Math.max (currentOffset - buffer.length, 0); rafHandle.seek (currentOffset); rafHandle.readFully (buffer); for (int i = buffer.length - 1; i &gt; -1; --i) { if (buffer[i] == '\n') { ++foundLines; if (foundLines == skipNLines) endOffset = currentOffset + i - 1; // we want the end to be BEFORE the newline } } } return endOffset; } } </code></pre> <hr> <hr> <h1>Alternative #2</h1> <ol> <li>Read from your file line by line</li> <li>On every successfully read line, insert the line at the back of your <code>LinkedList&lt;String&gt;</code></li> <li>If your <code>LinkedList&lt;String&gt;</code> contains more lines than you'd like to skip, remove the first entry and process it</li> <li>Repeat until there are no more lines to be read</li> </ol> <hr> <h2>Example code</h2> <pre><code>import java.io.InputStreamReader; import java.io.FileInputStream; import java.io.DataInputStream; import java.io.BufferedReader; import java.util.LinkedList; public class Example { protected static final int SKIP_N = 42; public static void main (String[] args) throws Exception { String line; LinkedList&lt;String&gt; lli = new LinkedList&lt;String&gt; (); FileInputStream fis = new FileInputStream ("/tmp/sample_file"); DataInputStream dis = new DataInputStream (fis); InputStreamReader isr = new InputStreamReader (dis); BufferedReader bre = new BufferedReader (isr); while ((line = bre.readLine ()) != null) { lli.addLast (line); if (lli.size () &gt; SKIP_N) { System.out.println (lli.removeFirst ()); } } dis.close (); } } </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. 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.
 

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