我有一个用Java编写的GUI程序,它使用System.out.println
将数据输出到命令行。该数据旨在通过管道传输到另一个程序中。例如,我将通过head
:
$ java MyProgram | head -n10
我希望我的程序在管道损坏时退出:在这种情况下,这应该在MyProgram
打印出十行文本后发生。
有a similar question on this site,其中的解决方案效果相当不错;例如,我可以在自己的线程中运行以下命令:
while(!System.out.checkError()) {
// sleep 100ms
}
System.exit(0);
问题是PrintStream.checkError()
似乎只有在您尝试打印到流并失败后才会返回true
。出于这个原因,我的程序实际上不会退出,直到它打印出 11个行文本:管道在前十后被破坏,但System.out
继续返回{{1}直到我试图通过第十一行。
打印出额外的垃圾'为了在true
上触发错误,行是不可能的,因为管道右侧的程序可能对它接收的数据非常敏感。
在PrintStream
中调用System.out.flush()
对PrintStream.checkError()
没有影响,即使PrintStream
的源代码表明它应该调用该类中的私有ensureOpen
方法
如何在不打印任何内容的情况下可靠地测试System.out
是否打开?
'真实世界'例如:假设我有一些程序consumer
接受命令行输入并对其执行某些操作。某些输入会使consumer
无声地失败。由于consumer
的输入有时很长而且深奥,我在Java中编写了一个GUI程序InputProvider
,我可以单击按钮并将相应的命令打印到stdout
。如果我将InputProvider
的输出传输到consumer
,那么我就能够以图形方式控制consumer
。
不幸的是,InputProvider
似乎没有办法在consumer
关闭时通知用户,除非尝试写入consumer
并获得某种异常。
答案 0 :(得分:2)
我认为你不能用Java解决这个问题。 System.out
之前没有任何问题,直到你写信给它失败。另一个进程(head
)已经结束,但Java进程无法知道。
所以我认为你有两个选择。
head
但是限制Java代码中的输出 - 然后你就知道何时停止答案 1 :(得分:1)
尝试为系统设置新流,以便您能够检查该流是否已关闭:OutputStream output = new FileOutputStream("c:\\data\\system.out.txt");
和PrintStream printOut = new PrintStream(output);
。然后在此处设置:System.setOut(printOut);
并在if中查看if(printOut.checkError())