0

I'm trying a tail implementation of the follow option in java. It is supposed to print the last ten lines from a dynamically changing file. How exactly is one supposed to keep the program running. What should be the while loop condition?

while (true) {
                Thread.sleep(1000);
                long len = file.length();
                long pointer = r.getFilePointer();
                if (len < pointer) {
                    //Do something
                }
                else if (len > pointer) {
                   //Do something
                }
             } 
Adway Dhillon
  • 77
  • 1
  • 4
  • 16

3 Answers3

2
import java.io.*;
import java.nio.channels.*;

public class Tail {
public static void main( String[] args ) throws Exception {

File f = new File( args[0] );
FileInputStream fis = new FileInputStream( f );
BufferedInputStream bis = new BufferedInputStream( fis );
FileChannel fc = fis.getChannel();
String line = null;
    long pos = fc.size();
    fc.position( pos );  // Positioning by using a FileChannel to reach EOF

    for(;;){
       Thread.sleep( 100 );
       long newpos = fc.size();  // Monitor new position
       while( pos < newpos ){    // new data?
           int c = bis.read();   // read and print
           System.out.print( (char)c );
           pos++;
       }
       pos = newpos;
    }
}
}

This inner loop is even better as there's only one bulk read and one write.

    if( newpos > pos ){
        ByteBuffer buffer = ByteBuffer.allocate( (int)(newpos - pos) );
        fc.read( buffer );
        System.out.print( new String( buffer.array()) );
        pos = newpos;
    }
laune
  • 31,114
  • 3
  • 29
  • 42
0
  1. Check the last modification time from the metadata of your file. use f.lastModified()
  2. If the time has changed dump the data from the line of last file size till end. Use random access file to reach till the desired point in the file fast.

    RandomAccessFile raF = new RandomAccessFile(f, "r");
    raF.seek(f.length());
    
  3. Save a pointer to the last line now.

Read more here -

https://freethreads.wordpress.com/2010/10/20/how-tail-f-work/ http://www.tutorialspoint.com/java/io/file_lastmodified.htm

Code:

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Main {
  public static void main(String args[]) throws InterruptedException, IOException {
    File f = new File("/home/mangat/hi");   
    RandomAccessFile raF = new RandomAccessFile(f, "r");
    long time = 0;
    String line = "";

    //First reach then end, No need to print already present content

    long fSize= f.length();
    while( line != null )  
    {               line = raF.readLine();  
    }  
    raF.seek(fSize);
    time = f.lastModified();

    //Now print the additions in the file from now on

    while (true) {
      if (time != f.lastModified()) {
       // System.out.println("changed");
        time = f.lastModified();
        System.out.println(f.length());
        raF.seek(f.length());
        line = raF.readLine();  
        while( line != null )  
        {   
           System.out.println(line);
           line = raF.readLine();  
        }  
      }

      Thread.sleep(100);
    }
  }
}
Mangat Rai Modi
  • 5,397
  • 8
  • 45
  • 75
-1

One way of doing it (I'm sure there are better ways) is store the last line of file in a variable outside the loop, update it every loop and only print out if something has changed, something like:

String oldLastLine;
String newLastLine;

while (true) {
    // sleep

    newLastLine = // read lastLine
    if (oldLastLine.equals(newLastLine)) {
        continue;
    }

    // check pointers

    oldLastLine = newLastLine;
}

To read the last line and in general more info about tail look at: Quickly read the last line of a text file?

About the code: It will basically skip the current iteration and won't do anything if the line hasn't changed. I haven't tested it so it may not work, but I hope you get the idea.

Edit:

As people have commented, this is not a fool-proof method, however, if you want to keep it simple you could read the last few lines. Furthermore, if you'd look at the link I gave previously, you'd find a working implementation of tail in Java.

Community
  • 1
  • 1
Crembo
  • 5,198
  • 3
  • 26
  • 30
  • What is line are added to fast? Reading last line only could make you miss some lines. What if same line was written twice? You will miss that too! – Mangat Rai Modi Jan 09 '15 at 10:13
  • What happens if lines are repeated? -1 – laune Jan 09 '15 at 10:27
  • Yeah fair enough, but if you wanted keep it simple you can just read the last few lines. Also, I gave a link to an answer that shows how to implement tail in Java. – Crembo Jan 09 '15 at 11:45