2010-02-05 4 views
13

Ich versuche herauszufinden, wie man eine Datei fortlaufend liest und sobald eine neue Zeile hinzugefügt wurde, gebe die Zeile aus. Ich mache das mit einem Sleep-Thread, aber es scheint nur durch die ganze Datei zu blasen und das Programm zu beenden.Wie liest du kontinuierlich eine Datei in Java?

Irgendwelche Vorschläge, was ich falsch mache?

Hier ist mein Code:

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 

Dank im Voraus

UPDATE: Ich habe die Linie seit geändert "während (br.nextLine) {" nur "while (TRUE) {"

+0

Dieser Code wird nicht kompiliert. Was ist "in"? –

+0

Nur ein Kommentar, aber Sie sollten in die Verwendung von Scanner-Objekten anstelle von BufferedReader schauen, sie neigen dazu, freundlicher zu sein, aber das wird diese Frage nicht beantworten. – Pace

+0

Noch nicht ok bei: 'while (br.nextLine)', 'nextLine ist kein gültiges Feld von' BufferedReader'. –

Antwort

15

Dies in etwas alt, aber ich habe den Mechanismus verwendet und es funktioniert ziemlich gut.

edit: Link funktioniert nicht mehr, aber ich fand es im Internet-Archiv https://web.archive.org/web/20160510001134/http://www.informit.com/guides/content.aspx?g=java&seqNum=226

Der Trick ist ein java.io.RandomAccessFile, zu verwenden und in regelmäßigen Abständen überprüfen, ob die Dateilänge größer, dass Ihre aktuelle Dateiposition ist. Wenn dies der Fall ist, lesen Sie die Daten. Wenn Sie die Länge treffen, warten Sie. waschen, spülen, wiederholen.

kopiert ich den Code, nur für den Fall, dass neue Verbindung stoppt

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

Link verweist nicht mehr auf eine Anleitung zum Beispiel. – makadus

+1

feste Verbindung und kopierten Code in Antwort – karoberts

+0

Awesome, danke! – makadus

2

Wie Ihr Code jetzt geschrieben ist, werden Sie Ihre while-Schleife nicht durchlaufen, wenn Ihre 'line == null', weil Sie überprüfen, ob es eine nächste Zeile hat, bevor Sie überhaupt in die Schleife kommen.

Versuchen Sie stattdessen, eine while(true){ } Schleife zu machen. Auf diese Weise werden Sie immer wieder durchforsten und Ihre Pause-Fälle auffangen, bis Sie eine Bedingung treffen, die das Programm beenden würde.

5

arbeiten Wenn Sie planen, diese auf einer angemessenen Größe Anwendung zu implementieren, wo mehrere Objekte in der Verarbeitung der neuen Linien interessiert sein könnte kommen die Datei, möchten Sie vielleicht die Observer Muster betrachten.

Das Objekt, das aus der Datei liest, benachrichtigt jedes Objekt, das es abonniert hat, sobald eine Zeile verarbeitet wurde. Dadurch können Sie die Logik in der Klasse, in der sie benötigt wird, gut trennen.

Verwandte Themen