1

我正在监视另一个不断写入它的 java 进程的日志文件。这两个进程(监控应用程序和被监控应用程序)运行在 linux 发行版 centos 上。

问题是每次我重新启动受监控的应用程序时,监控应用程序似乎都会收到此错误:

java.io.IOException:在 FileMonitor 的 LogMonster.fileChanged(LogMonitor.java:57) 的 java.io.RandomAccessFile.read(RandomAccessFile.java:361) 的 java.io.RandomAccessFile.readBytes(Native Method) 的输入/输出错误.fireFileChangeEvent(FileMonitor.java:96) 在 FileMonitor$FileMonitorTask.run(FileMonitor.java:128) 在 java.util.TimerThread.mainLoop(Timer.java:512) 在 java.util.TimerThread.run(Timer.java: 462)

我保留了一个 Map ,其中文件名作为键,RandomAccessFile 对象作为值,并在将此对象添加为侦听器后按如下方式填充它:

monitor.addFileChangeListener(logMonitor, LogFileName, LogMonitor_Properties.getTimeDelay()); randomAccessFile_list.put(LogFileName, new RandomAccessFile(LogFileName, "r"));

每次修改文件时都会触发一个事件,并且它在 eventFired 函数中,我试图在受监控的应用程序重新启动后从 RandomAccessFile 读取内容(在重新启动之前它工作正常)。

'fileChanged' 函数中的以下代码行导致错误:

randomAccessFile_list.get(file.getAbsolutePath()).read(byteArray);

我使用 bash 脚本来杀死应用程序的所有版本,然后在“go”文件中重新启动它。

go内容:

cd /path/to/app

。/杀

nohup ./app.run &

杀戮内容:

杀死 -9 $(lsof app.run| awk '{print $2}')

杀死 -9 $(lsof app.log| awk '{print $2}')

杀死 -9 $(lsof app.go| awk '{print $2}')

app.run 的内容:

./app.go >>app.log 2>&1

app.log 的内容:只是应用程序的文本输出。

app.go 的内容:

. /path/to/some/other/location/setClassPath.go

导出 CLASSPATH=$CLASSPATH

回声 $CLASSPATH

/usr/local/jdk1.6.0_27/bin/java -cp $CLASSPATH MyApp

我很抱歉在您阅读之前发布了一个看起来很累的问题,但我真的无能为力,任何帮助将不胜感激。

提前致谢。

4

1 回答 1

1

从方法名称看来,您正在使用进行文件监控。它实际上并没有打开文件,它只是偶尔统计一下。

然后,您还将为地图中的文件保持一个单独的文件句柄。

库仅在修改时间更改时触发事件 - 这并不意味着文件中添加了任何新数据。然后,您显然尝试从您的文件句柄中读取并获得 IO 异常。

这种方法存在许多问题,但是如果不查看更多代码,就不可能准确地告诉您问题出在哪里。我猜测受监控的进程在重新启动时正在截断、删除或对文件执行其他操作,这会使您打开的文件句柄无效。

当您想要重新加载整个文件(通常是属性文件或正在编辑的文档)时,通常会使用这样的文件监视,而不是尝试执行“尾部”操作。

于 2012-08-17T16:00:41.277 回答