有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java刷新系统。用自己的记录器输出

我创建了我自己的小记录器来代替系统。出来普林顿

LogManager.getLogManager().reset();
logger = Logger.getLogger(this.toString());
logger.setLevel(loglevel);
Formatter formatter = new Formatter() {
    public String format(LogRecord record) {
        return new Date().toString().substring(11, 20) + record.getLevel()+" " + formatMessage(record) + System.getProperty("line.separator");
    }
};
logger.addHandler(new StreamHandler(System.out, formatter));
LogManager.getLogManager().addLogger(logger);

目前,消息不会被刷新,因此它们只在应用程序终止后出现。有没有一种方法可以在打印消息后刷新消息,而不创建新类或添加许多代码行?我想让这个代码尽可能短


共 (1) 个答案

  1. # 1 楼答案

    问题是StreamHandler.setOutputStream将给定流包装在OutputStreamWriter中,根据javadocs,该OutputStreamWriter将:

    The resulting bytes are accumulated in a buffer before being written to the underlying output stream. The size of this buffer may be specified, but by default it is large enough for most purposes.

    因此,没有办法调用StreamHandler.flush强制将这些字节发送到控制台

    因为您不想创建一个新类,所以可以使用ConsoleHandler,它将刷新到控制台,但默认情况下将写入错误流。如果您还没有启动任何其他线程,您可以通过执行以下操作来解决此问题:

    //Global resource so ensure single thread.
    final PrintStream err = System.err;
    System.setErr(System.out);
    try {
        ConsoleHandler ch = new ConsoleHandler();
        ch.setFormatter(formatter);
        logger.addHandler(ch);
    } finally {
        System.setErr(err);
    }
    

    子类确实是最好的选择,因为您可以通过调用LogManager.getLogManager().reset()或调用StreamHandler.setOutputStream来意外地关闭System.out,这意味着您根本看不到任何输出

    public class OutConsoleHandler extends StreamHandler {
        public OutConsoleHandler(OutputStream out, Formatter f) {
            super(out, f);
        }
    
        @Override
        public synchronized void publish(LogRecord record) {
            super.publish(record);
            flush();
        }
    
        @Override
        public void close() throws SecurityException {
            flush();
        }
    }