2010-02-05 25 views
13

Tôi đang cố gắng tìm ra cách liên tục đọc một tệp và một khi có dòng mới được thêm vào, hãy xuất dòng. Tôi đang làm điều này bằng cách sử dụng một thread ngủ tuy nhiên nó chỉ có vẻ như thổi qua toàn bộ tập tin và thoát khỏi chương trình.Làm thế nào để bạn liên tục đọc một tệp trong Java?

Bất kỳ đề xuất nào tôi đang làm sai?

Đây là mã của tôi:

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 

cảm ơn trước

UPDATE: Tôi đã thay đổi kể từ dòng "while (br.nextLine) {" để chỉ "while (TRUE) {"

+0

Mã này sẽ không biên dịch. 'In' là gì? –

+0

Chỉ cần một bình luận nhưng bạn nên xem xét sử dụng các đối tượng Scanner thay vì BufferedReader, chúng có xu hướng thân thiện hơn, tuy nhiên điều đó sẽ không trả lời câu hỏi này. – Pace

+0

Vẫn không ổn tại: 'while (br.nextLine)', 'nextLine không phải là trường hợp lệ của' BufferedReader'. –

Trả lời

15

Điều này hơi cũ, nhưng tôi đã sử dụng cơ chế và hoạt động khá tốt.

chỉnh sửa: liên kết không còn hoạt động, nhưng tôi tìm thấy nó trong các kho lưu trữ internet https://web.archive.org/web/20160510001134/http://www.informit.com/guides/content.aspx?g=java&seqNum=226

Bí quyết là sử dụng một java.io.RandomAccessFile, và định kỳ kiểm tra xem độ dài tập tin lớn rằng vị trí tập tin hiện tại của bạn. Nếu có, thì bạn đọc dữ liệu. Khi bạn nhấn chiều dài, bạn chờ đợi. rửa, rửa sạch, lặp lại.

tôi sao chép mã này, chỉ trong trường hợp liên kết mới ngừng hoạt động

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

Liên kết không còn trỏ đến hướng dẫn ví dụ. – makadus

+1

liên kết cố định và mã được sao chép vào câu trả lời – karoberts

+0

Tuyệt vời, cảm ơn bạn! – makadus

2

Cách mã của bạn được viết ngay bây giờ, bạn sẽ không đi qua vòng lặp while khi 'line == null' vì bạn đang kiểm tra xem nó có dòng tiếp theo hay không trước khi bạn vào vòng lặp.

Thay vào đó, hãy thử thực hiện vòng lặp while(true){ }. Bằng cách đó, bạn sẽ luôn luôn được lặp qua nó, bắt các trường hợp tạm dừng của bạn, cho đến khi bạn nhấn một điều kiện mà có thể gây ra chương trình kết thúc.

5

Nếu bạn đang lập kế hoạch để thực hiện điều này trên một ứng dụng có kích thước hợp lý nơi nhiều đối tượng có thể quan tâm trong việc xử lý các dòng mới đến tệp, bạn có thể muốn xem xét mẫu Observer.

Đọc đối tượng từ tệp sẽ thông báo cho từng đối tượng đã đăng ký ngay khi một dòng đã được xử lý. Điều này sẽ cho phép bạn giữ logic được phân tách tốt trên lớp khi cần.

Các vấn đề liên quan