【发布时间】:2015-04-20 20:40:53
【问题描述】:
我正在使用一个 Java 控制台应用程序,该应用程序必须写入(附加)到两个单独的文件,对应于 OUT 和 ERR 流。 tail 和 grep 等外部实用程序将实时监控这些文件。我开始通过Appendable 接口写入这两个流,但在应用程序完成执行之前,文件似乎不会反映任何更改,在输出流上刷新和关闭之后。
服务
package com.mycompany;
public class Service {
private Appendable outlog;
private Appendable errlog;
public Service(Appendable outlog, Appendable errlog) {
this.outlog = outlog;
this.errlog = errlog;
}
public void executeTask() throws Exception {
outlog.append("task execution started\n");
Thread.sleep(30 * 1000);
outlog.append("task execution completed\n");
}
}
应用程序
package com.mycompany;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
public class Application {
public static void main(String[] args) throws Exception {
PrintWriter outlog = new PrintWriter(new BufferedWriter(new FileWriter("application.log")));
PrintWriter errlog = new PrintWriter(new BufferedWriter(new FileWriter("application-err.log")));
Service service = new Service(outlog, errlog);
service.executeTask();
outlog.flush();
outlog.close();
errlog.flush();
errlog.close();
}
}
我的设计从根本上是错误的,还是我应该以更好、更有效的方式来做这件事?
【问题讨论】:
-
您是否尝试过使用日志库:slf4j、logback、log4j?
-
应用程序可以控制这些 log 文件的名称,因此日志库在这种情况下不会很有帮助。将根据执行时间和用户身份生成多个文件。
-
你试过不关闭就冲洗吗?例如,每次写入日志后刷新?
-
调用
flush()确实应该可以将输出刷新到磁盘。这有可能在Windows上吗?还是将日志文件写入 NFS 等网络文件系统,而阅读器位于另一台主机上?您发布的代码实际上并未编译,我怀疑它是伪代码。您能否编辑您的问题以包含一个实际工作的示例程序? -
如果您获得 FileDescriptor 并在每次写入后调用 sync() 方法,然后刷新,文件内容将对其他进程可见。您不必关闭该文件。
标签: java logging file-io nio tail