2010-02-05 8 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

이 코드는 컴파일되지 않습니다. '안에 '란 무엇입니까? –

+0

다만 코멘트이지만 BufferedReader 대신 Scanner 객체를 사용하여 조사해야하지만,이 질문에 답하지 않더라도 더 친숙한 경향이 있습니다. – 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 회 돌이에 들어가기 전에 다음 줄이 있는지 확인하기 때문에 '회 돌이 == null'일 때 while 회 돌이를 수행하지 않습니다.

대신에 while(true){ } 루프를 사용해보십시오. 그렇게하면 프로그램이 종료되는 조건에 도달 할 때까지 일시 중지 사례를 포착하여 항상 반복됩니다.

5

작동을 중지하는 경우에 대비, 코드를 복사 파일의 경우, Observer 패턴을 고려할 수 있습니다.

파일에서 읽는 개체는 줄 처리가 끝나면 바로 구독하는 각 개체에 알립니다. 이렇게하면 필요한 클래스에서 논리를 잘 구분할 수 있습니다.

관련 문제