Как Вы непрерывно читаете файл в Java?

Я пытаюсь выяснить, как непрерывно читать файл и после того как существует добавленная новая строка, произведите строку. Я делаю это использование потока сна однако, это просто, кажется, дует через целый файл и выходит из программы.

Какие-либо предложения, что я делаю неправильно?

Вот мой код:

import java.io.*;
import java.lang.*;
import java.util.*;

class jtail { 
    public static void main (String args[])
            throws InterruptedException, IOException{ 

        BufferedReader br = new BufferedReader(
                new FileReader("\\\\server01\\data\\CommissionPlanLog.txt"));

        String line = null;
        while (br.nextLine ) {
            line = br.readLine();
            if (line == null) {
                //wait until there is more of the file for us to read
                Thread.sleep(1000);
            }
            else {
                System.out.println(line);
            }
        }
    } //end main 
} //end class jtail 

заранее спасибо

ОБНОВЛЕНИЕ: я с тех пор изменил строку "в то время как (br.nextLine) {" только к "в то время как (TRUE) {"

15
задан phill 24 February 2010 в 14:33
поделиться

3 ответа

Это несколько устарело, но я использовал этот механизм, и он работает довольно хорошо.

edit: ссылка больше не работает, но я нашел ее в интернет-архиве https://web.archive.org/web/20160510001134/http://www.informit.com/ guides / content.aspx? g = java & seqNum = 226

Уловка состоит в том, чтобы использовать java.io.RandomAccessFile и периодически проверять, превышает ли длина файла текущее положение файла. Если да, то вы читаете данные. Когда вы достигнете длины, вы ждете. постирать, прополоскать, повторить.

Я скопировал код на тот случай, если новая ссылка перестанет работать

package com.javasrc.tuning.agent.logfile;

import java.io.*;
import java.util.*;

/**
 * A log file tailer is designed to monitor a log file and send notifications
 * when new lines are added to the log file. This class has a notification
 * strategy similar to a SAX parser: implement the LogFileTailerListener interface,
 * create a LogFileTailer to tail your log file, add yourself as a listener, and
 * start the LogFileTailer. It is your job to interpret the results, build meaningful
 * sets of data, etc. This tailer simply fires notifications containing new log file lines, 
 * one at a time.
 */
public class LogFileTailer extends Thread 
{
  /**
   * How frequently to check for file changes; defaults to 5 seconds
   */
  private long sampleInterval = 5000;

  /**
   * The log file to tail
   */
  private File logfile;

  /**
   * Defines whether the log file tailer should include the entire contents
   * of the exising log file or tail from the end of the file when the tailer starts
   */
  private boolean startAtBeginning = false;

  /**
   * Is the tailer currently tailing?
   */
  private boolean tailing = false;

  /**
   * Set of listeners
   */
  private Set listeners = new HashSet();

  /**
   * Creates a new log file tailer that tails an existing file and checks the file for
   * updates every 5000ms
   */
  public LogFileTailer( File file )
  {
    this.logfile = file;
  }

  /**
   * Creates a new log file tailer
   * 
   * @param file         The file to tail
   * @param sampleInterval    How often to check for updates to the log file (default = 5000ms)
   * @param startAtBeginning   Should the tailer simply tail or should it process the entire
   *               file and continue tailing (true) or simply start tailing from the 
   *               end of the file
   */
  public LogFileTailer( File file, long sampleInterval, boolean startAtBeginning )
  {
    this.logfile = file;
    this.sampleInterval = sampleInterval;
  }

  public void addLogFileTailerListener( LogFileTailerListener l )
  {
    this.listeners.add( l );
  }

  public void removeLogFileTailerListener( LogFileTailerListener l )
  {
    this.listeners.remove( l );
  }

  protected void fireNewLogFileLine( String line )
  {
    for( Iterator i=this.listeners.iterator(); i.hasNext(); )
    {
      LogFileTailerListener l = ( LogFileTailerListener )i.next();
      l.newLogFileLine( line );
    }
  }

  public void stopTailing()
  {
    this.tailing = false;
  }

  public void run()
  {
    // The file pointer keeps track of where we are in the file
    long filePointer = 0;

    // Determine start point
    if( this.startAtBeginning )
    {
      filePointer = 0;
    }
    else
    {
      filePointer = this.logfile.length();
    }

    try
    {
      // Start tailing
      this.tailing = true;
      RandomAccessFile file = new RandomAccessFile( logfile, "r" );
      while( this.tailing )
      {
        try
        {  
          // Compare the length of the file to the file pointer
          long fileLength = this.logfile.length();
          if( fileLength < filePointer ) 
          {
            // Log file must have been rotated or deleted; 
            // reopen the file and reset the file pointer
            file = new RandomAccessFile( logfile, "r" );
            filePointer = 0;
          }

          if( fileLength > filePointer ) 
          {
            // There is data to read
            file.seek( filePointer );
            String line = file.readLine();
            while( line != null )
            {
              this.fireNewLogFileLine( line );
              line = file.readLine();
            }
            filePointer = file.getFilePointer();
          }

          // Sleep for the specified interval
          sleep( this.sampleInterval );
        }
        catch( Exception e )
        {
        }
      }

      // Close the file that we are tailing
      file.close();
    }
    catch( Exception e )
    {
      e.printStackTrace();
    }
  }
}
17
ответ дан 1 December 2019 в 02:37
поделиться

Если вы планируете реализовать это в приложении разумного размера, где несколько объектов могут быть заинтересованы в обработке новых строк, поступающих в файл, вы можете рассмотреть шаблон Observer .

При чтении объекта из файла каждый объект, на который он подписан, будет уведомлен, как только строка будет обработана. Это позволит вам сохранить логику, четко разделенную по классу, где это необходимо.

6
ответ дан 1 December 2019 в 02:37
поделиться

Ваш код теперь написан так, что вы не будете проходить цикл while, когда ваш 'line == null', потому что вы проверяете, что он имеет следующую строку еще до того, как вы войдете в цикл.

Вместо этого попробуйте выполнить цикл while (true) {} . Таким образом, вы всегда будете перебирать его, улавливая случаи паузы, пока не достигнете условия, которое приведет к завершению программы.

2
ответ дан 1 December 2019 в 02:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: