BufferedReader读取空行而不是新添加的行



我目前正在开发一个管理远程minecraft服务器的应用程序,我正在做的第一件事就是观察minecraft控制台的消息。我通过观察minecraft服务器复制其输出的最新.log文本文件来做到这一点。日志消息每条添加到一个换行中,因此监视的基本工作流是:

start -> read all existing lines of latest.log -> watch for file change notifications on latest.log -> 
read newly added line(s) -> wait for next file change notification

我实现了下面的类来做到这一点:

public class McServerService {



private String directory;


private List<String> currentLog;

private Thread logObserverThread;
private PropertyChangeSupport pcsupport;


public McServerService (String directory) {
this.currentLog = new ArrayList<String>();
this.directory = directory;
this.pcsupport = new PropertyChangeSupport(this);
}

public void startWatching ()  {
this.logObserverThread = new Thread(new LogObserverThreadImpl(this.directory));
this.logObserverThread.start();
}

public void addNewLogLine (String newLogLine) {
this.pcsupport.firePropertyChange("currentLog", this.currentLog, newLogLine);
this.currentLog.add(newLogLine);
System.out.println("addNewLogLine: " + newLogLine);

}

public void addPropertyChangeListener (PropertyChangeListener pcl) {
this.pcsupport.addPropertyChangeListener(pcl);
}

public void removePropertyChangeListener (PropertyChangeListener pcl) {
this.pcsupport.removePropertyChangeListener(pcl);
}



private class LogObserverThreadImpl implements Runnable {

BufferedReader br;
WatchService watchService;

private LogObserverThreadImpl (String directory) {
try {
this.br = new BufferedReader(new java.io.FileReader(directory + "\" + "latest.log"));
String nextLine = this.br.readLine();
while (nextLine != null) {
McServerService.this.currentLog.add(nextLine);
System.out.println("init: " + nextLine);
this.br.mark(2048);
nextLine = this.br.readLine();
System.out.println("init: " + nextLine);
}
this.br.reset();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
Path path = Paths.get(directory);
try {
System.out.println("entered try");
this.watchService = FileSystems.getDefault().newWatchService();
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);
WatchKey key;
while ((key = this.watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
if (event.context().toString().equals("latest.log")) {
String line = this.br.readLine();
/*
* if (line.equalsIgnoreCase("")) { line = this.br.readLine(); }
*/
McServerService.this.addNewLogLine(line);
System.out.println("thread: " + line);
}
}
key.reset();
}
System.out.println("after while");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}




}

现有的最新的.log文本文件将按照预期读取其所有行,然后以空结束,但是当添加两行

gadhsjlhgadsjlkh
jlhkadshljhads

并将文件保存在每行之后,输出如下所示:

init: null //"last" line of existing file
entered try
//now adding the two lines
pclimlp: 
addNewLogLine: 
thread: 
pclimlp: gadhsjlhgadsjlkh
addNewLogLine: gadhsjlhgadsjlkh
thread: gadhsjlhgadsjlkh

这个问题可以通过取消"等号检查的注释来解决。:

while ((key = this.watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
if (event.context().toString().equals("latest.log")) {
String line = this.br.readLine();
/*
* if (line.equalsIgnoreCase("")) { line = this.br.readLine(); }
*/
McServerService.this.addNewLogLine(line);
System.out.println("thread: " + line);
}
}
key.reset();
}

但是为什么bufferedreader首先读取空行呢?我理解null,如果BufferedReader还没有更新,但为什么空行?此外,如果我再次手动保存文件(不添加更多行或任何东西),BufferedReader将读取之前没有读取的行,并且不会跳过它。有人能解释一下是什么导致了这种行为吗?

bufferedread . readline()读取到下一个换行符或文件结束。

所以当读取这个文件时:

[......]
[21:34:31] [Server thread/INFO]: [removed] left the game

BufferedReader给出如下输出:

[......]
init: [21:34:31] [Server thread/INFO]: [removed] left the game
init: null

"init:";仅为调试目的而添加。当附加

xx
ghasjdkhajs

所以文件的结尾看起来像这样:

[21:34:31] [Server thread/INFO]: [removed] left the gamexx
ghasjdkhajs

这将导致以下输出:

pclimlp: xx
addNewLogLine: xx
thread: xx

所以BufferedReader在文件的末尾就在

之后
left the game

所以当添加

xxrnghasjdkhajs

BufferedReader读取到下一个换行符。如果没有"xx"添加之前是没有下一个换行,所以BufferedReader将返回"就像刚才那个问题。

最新更新