你如何用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 

提前致谢

更新:我已经改变了行“while(br.nextLine){”只是“while(TRUE){”

这有点旧,但我已经使用了机制,它运作得很好。

编辑:链接不再有效,但我在互联网档案中找到了它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(); } } } 

如果您计划在合理大小的应用程序上实现此function,其中多个对象可能有兴趣处理进入该文件的新行,您可能需要考虑Observer模式。

从文件读取的对象将在处理完一行后立即通知订阅它的每个对象。 这将允许您在需要它的类上保持逻辑分离。

现在编写代码的方式,当你的’line == null’时你不会经历你的while循环,因为你在进入循环之前检查它是否有下一行。

相反,尝试做一个while(true){ }循环。 这样,您将始终循环遍历它,捕获您的暂停情况,直到您遇到导致程序结束的情况。

如果您没有从头开始编写此代码的要求,也请考虑org.apache.commons.io.input.Tailer 。