Java + Eclipse:同步标准输出和标准错误

发布于 2024-09-03 02:43:24 字数 427 浏览 10 评论 0 原文

我使用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 后等待几毫秒。

I use Eclipse. When I have an application like this:

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

The output looks many times like this:

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

Is there a way to synchronize these two output streams? Of course without waiting a few milliseconds after the block of 20 times Hello World and waiting a few milliseconds after printing ERROR.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡淡の花香 2024-09-10 02:43:24

不管你相信与否,刷新在这里不是一个解决方案......

如果一个流导致“底层操作系统提供的抽象”(例如磁盘驱动器或控制台),那么剩余的字节“将被传递到操作系统进行写入” ;它不能保证它们确实被写入...”(参见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?

人间不值得 2024-09-10 02:43:24

对于“严肃”的使用,我不喜欢直接写入 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

参见

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 quirky PrintStream (is it a byte stream or a character stream?). If you wrap the output streams in your own PrintWriter, you can then set it to flush automatically - the second argument in the constructor is auto-flush.

E.g.

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

See

铁轨上的流浪者 2024-09-10 02:43:24

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 try System.out.flush() and System.err.flush().

空气里的味道 2024-09-10 02:43:24

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

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

System.setErr(System.out);

或者通过 System.setOut()

System.setOut(System.err);

这样做的缺点是它可能会改变语法突出显示:例如,某些 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:

System.setErr(System.out);

Or the other way around via System.setOut()

System.setOut(System.err);

A downside of this is that it may change syntax-highlighting: e.g. some IDEs may highlight text on stderr and stdout differently

人心善变 2024-09-10 02:43:24

添加刷新后跟 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 秒

Add a flush followed by a Thread.sleep(1), 99.9% output order will be correct.

For example, this will display as expected.

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 );

The only drawback is the sleep for 1 millisecond, i.e. 1/1000 second

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文