Java + Eclipse:同步标准输出和标准错误
我使用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
后等待几毫秒。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不管你相信与否,刷新在这里不是一个解决方案......
如果一个流导致“底层操作系统提供的抽象”(例如磁盘驱动器或控制台),那么剩余的字节“将被传递到操作系统进行写入” ;它不能保证它们确实被写入...”(参见OutputStream 文档)。这里的关键是,如果操作系统选择的话,它可以以不同的顺序处理来自不同流的刷新。
我刚刚在我的程序中发生了这种情况。我在两条正常消息之间出现一条错误消息,两条正常消息都在错误消息出现之前刷新。
所以问题仍然存在,是否有内置的方法来同步两个流?还是我们必须手动处理?
Believe it or not, flushing is not a solution here....
If a stream leads to "an abstraction provided by the underlying operating system" (e.g. a disk drive or console) then remaining bytes "are passed to the operating system for writing; it does not guarantee that they are actually written..." (see the OutputStream documentation). The key here is that the OS can handle flushes from different streams in different orders if it so chooses.
I just had this happen in my program. I had an error message appear between two normal message, both of which had flushed before the error message did.
So the question remains, is there a built-in way to synchronize two streams? Or do we have to handle that manually?
对于“严肃”的使用,我不喜欢直接写入
System.out/System.err
,因为它对目的地进行硬编码,而且它还使用相当古怪的PrintStream
>(是字节流还是字符流?)。如果您将输出流包装在自己的PrintWriter
中,则可以将其设置为自动刷新 - 构造函数中的第二个参数是auto-flush
。例如
参见
For "serious" use, I prefer not writing directly to
System.out/System.err
, since it hard-codes the destination, and it also it uses the rather quirkyPrintStream
(is it a byte stream or a character stream?). If you wrap the output streams in your ownPrintWriter
, you can then set it to flush automatically - the second argument in the constructor isauto-flush
.E.g.
See
System.out和System.err是普通的
PrintStream
对象(它们提供了flush()方法),所以尝试一下System.out.flush()
和System. err.flush()。
System.out and System.err are ordinary
PrintStream
objects (which provide a flush() method), so trySystem.out.flush()
andSystem.err.flush()
.AFAIK 没有可靠的方法来强制同步 2 个不相关的流。
一种解决方法是仅使用一个流:例如使用 System.setErr() 重定向到 err,以便所有内容都打印在错误流上:
或者通过 System.setOut()
这样做的缺点是它可能会改变语法突出显示:例如,某些 IDE 可能会以不同方式突出显示 stderr 和 stdout 上的文本
AFAIK there is no reliable way to force a sync on 2 unrelated streams.
A workaround is to use only one stream: e.g. use System.setErr() to redirect out to err, so that everything is printed on the error stream:
Or the other way around via System.setOut()
A downside of this is that it may change syntax-highlighting: e.g. some IDEs may highlight text on stderr and stdout differently
添加刷新后跟 Thread.sleep(1),99.9% 的输出顺序将是正确的。
例如,这将按预期显示。
唯一的缺点是睡眠时间为 1 毫秒,即 1/1000 秒
Add a flush followed by a
Thread.sleep(1)
, 99.9% output order will be correct.For example, this will display as expected.
The only drawback is the sleep for 1 millisecond, i.e. 1/1000 second