当我使用System.out.println
打印出我的日志消息时,我正在编写一个基本的服务器程序。我写了一个基本的类文件,用它来写出日志。如果我写:Java PrintStream重定向意外行为
System.out.println("Hello, world!");
System.out.println("Goodbye, world");
所需的输出将是:
Log message - Hello, world!
Log message - Goodbye, world!
结束意外事件发生不匹配所需的输出。相反,它输出到以下内容。
Log message - Hello, world!
Goodbye, world!
主方法的代码:
public static void main(String[] args){
LogManager.start();
System.out.println("Hello, world!");
System.out.println("Goodbye, world!");
LogManager.stop();
}
类LogManager的切换即打印出来到默认PrintStream
,并保持旧的拷贝打印出日志消息。但是,“日志消息 - ”并不总是以前缀为前缀。虽然在每次呼叫println
之间睡眠2000毫秒时,输出如下所示。
Log message - Hello, world!
Log message - Goodbye, world!Log message -
LogManager的代码如下。
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
public class LogManager implements Runnable{
private final PrintStream ps;
private final OutputStream out;
private static boolean cont = true;
public static void start(){
OutputStream stdout = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(stdout);
Thread th = new Thread(new LogManager(System.out, stdout));
System.setOut(ps);
th.start();
}
public static void stop(){
cont = false;
}
public LogManager(PrintStream std, OutputStream out){
this.ps = std;
this.out = out;
}
@Override
public void run() {
ByteArrayOutputStream baos = (ByteArrayOutputStream) out;
while(true){
if(!cont) return;
byte[] bytes = baos.toByteArray();
if(bytes.length > 0){
baos.reset();
ps.print("Log message - " + new String(bytes));
}
}
}
}
有人请指点我做错了什么,非常感谢帮助。我希望远离图书馆,因为我希望将JAR的大小保持在最低限度,并且不需要包含额外的软件包,但主要是为了知道我没有使用任何其他软件库来实现我正在做的事情。
我试过了,但它似乎产生相同的结果。前缀仅添加到某些日志中。我相信这可能与缓冲有关。我做了'cont' volatile,并且将循环中的代码切换到了您所显示的代码,但它似乎仍然执行相同的操作。 – Garhoogin
@Garhoogin更新 – yshavit