2010-02-05 4 views
13

Я пытаюсь понять, как постоянно читать файл, и после добавления новой строки выведите строку. Я делаю это, используя поток сна, но он просто пробивает весь файл и выходит из программы.Как вы постоянно читаете файл на 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 

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

UPDATE: С тех пор я изменил линию "а (br.nextLine) {" просто "в то время как (TRUE) {"

+0

Этот код не компилируется. Что такое 'in'? –

+0

Просто комментарий, но вы должны изучить использование объектов Scanner вместо BufferedReader, они, как правило, более дружелюбны, однако это не ответит на этот вопрос. – Pace

+0

Все еще не в порядке: 'while (br.nextLine)', 'nextLine не является допустимым полем' BufferedReader'. –

ответ

15

Это несколько старый, но я использовал механизм, и он работает очень хорошо. не

редактировать: ссылка больше не работает, но я нашел в архиве интернет 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(); 
    } 
    } 
} 
+0

Ссылка больше не указывает на руководство, например. – makadus

+1

фиксированная ссылка и скопированный код в ответ – karoberts

+0

Удивительный, спасибо! – makadus

2

Как ваш код написан сейчас, вы не пройдете свой цикл while, когда ваша строка «нуль», потому что вы проверяете, что она имеет следующую строку, прежде чем вы даже попадете в цикл.

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

5

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

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