在Unix中关注像tail这样的文件

时间:2015-01-09 09:42:18

标签: java file-io io while-loop

我尝试在java中执行follow选项的尾部实现。它应该从动态变化的文件中打印最后十行。一个人应该如何保持程序运行。什么应该是while循环条件?

while (true) {
                Thread.sleep(1000);
                long len = file.length();
                long pointer = r.getFilePointer();
                if (len < pointer) {
                    //Do something
                }
                else if (len > pointer) {
                   //Do something
                }
             } 

3 个答案:

答案 0 :(得分: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;
    }
}
}

这个内循环甚至更好,因为只有一个批量读取和一个写入。

    if( newpos > pos ){
        ByteBuffer buffer = ByteBuffer.allocate( (int)(newpos - pos) );
        fc.read( buffer );
        System.out.print( new String( buffer.array()) );
        pos = newpos;
    }

答案 1 :(得分:0)

  1. 从文件的元数据中检查上次修改时间。使用f.lastModified()
  2. 如果时间已更改,则将数据从最后一个文件大小的行转储到结束。使用随机访问文件快速到达文件中的所需点。

    RandomAccessFile raF = new RandomAccessFile(f, "r");
    raF.seek(f.length());
    
  3. 立即将指针保存到最后一行。

  4. 在这里阅读更多内容 -

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

    <强>代码:

    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);
        }
      }
    }
    

答案 2 :(得分:-1)

这样做的一种方式(我确信有更好的方法)是将文件的最后一行存储在循环外的变量中,每次循环更新它,只有在某些内容发生变化时才打印出来,例如:

String oldLastLine;
String newLastLine;

while (true) {
    // sleep

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

    // check pointers

    oldLastLine = newLastLine;
}

要阅读最后一行,一般有关尾部的更多信息: Quickly read the last line of a text file?

关于代码: 它基本上会跳过当前的迭代,如果线路没有改变则不会做任何事情。 我没有测试过它可能不起作用,但我希望你能得到这个想法。

修改

正如人们所评论的那样,这不是一种万无一失的方法,但是,如果你想保持简单,你可以阅读最后几行。此外,如果您查看我之前提供的链接,您会发现Java的尾部工作实现。