12

我使用 Eclipse。当我有这样的应用程序时:

write 20 times 'Hello World\n' to stdout
write 'ERROR\n' to stderr
write 5 times 'Hello  World\n' to stdout

输出看起来很多次是这样的:

Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
...
Hello World
Hello World
Hello World
ERROR

有没有办法同步这两个输出流?当然不需要等待 20 次块后的Hello World几毫秒和打印后的几毫秒ERROR

4

5 回答 5

8

信不信由你,冲洗在这里不是解决方案....

如果一个流导致“底层操作系统提供的抽象”(例如磁盘驱动器或控制台),那么剩余的字节“被传递给操作系统进行写入;它不能保证它们实际上是被写入的......”(请参阅OutputStream 文档)。这里的关键是,如果操作系统愿意,它可以以不同的顺序处理来自不同流的刷新。

我刚刚在我的程序中发生了这种情况。我在两条正常消息之间出现了一条错误消息,这两条消息在错误消息出现之前都已刷新。

所以问题仍然存在,是否有同步两个流的内置方法?还是我们必须手动处理?

于 2010-11-17T01:03:19.557 回答
7

对于“严肃”的使用,我不喜欢直接写入System.out/System.err,因为它对目标进行硬编码,而且它还使用了相当古怪的PrintStream(是字节流还是字符流?)。如果您将输出流包装在自己的文件PrintWriter中,则可以将其设置为自动刷新 - 构造函数中的第二个参数是auto-flush.

例如

PrintWriter out = new PrintWriter(System.out, true);
PrintWriter err = new PrintWriter(System.err, true);

out.println("Hello world");
//this will flush after writing the end of line

于 2010-05-24T12:43:15.313 回答
3

System.out 和 System.err 是普通PrintStream对象(它们提供了一个 flush() 方法),所以请尝试System.out.flush()System.err.flush().

于 2010-05-24T12:23:16.397 回答
1

AFAIK 没有可靠的方法来强制同步 2 个不相关的流。

一种解决方法是仅使用一个流:例​​如,使用System.setErr()重定向到 err,以便将所有内容都打印在错误流上:

System.setErr(System.out);

或者通过System.setOut() 反过来

System.setOut(System.err);

这样做的一个缺点是它可能会改变语法突出显示:例如,某些 IDE 可能会以不同的方式突出显示 stderr 和 stdout 上的文本

于 2018-05-26T16:47:48.993 回答
0

添加一个同花顺后跟一个Thread.sleep(1), 99.9% 的输出顺序将是正确的。

例如,这将按预期显示。

System.out.println( "stdout 1" ); System.out.flush(); Thread.sleep( 1 );
System.err.println( "stderr 1" ); System.err.flush(); Thread.sleep( 1 );
System.out.println( "stdout 2" ); System.out.flush(); Thread.sleep( 1 );
System.err.println( "stderr 2" ); System.err.flush(); Thread.sleep( 1 );

唯一的缺点是休眠1毫秒,即1/1000秒

于 2012-05-08T20:32:11.907 回答