发生的情况是 SIGPIPE 异常导致 IOException。
对于大多数OutputStream
和Writer
类,此异常通过“write”方法传播,并且必须由调用者处理。
但是,当您写入 System.out 时,您使用的是PrintStream
,并且该类通过设计会照顾IOException
您。正如javadoc所说:
APrintStream
向另一个输出流添加了功能,即能够方便地打印各种数据值的表示。还提供了另外两个功能。与其他输出流不同, aPrintStream
从不抛出IOException
; 相反,异常情况只是设置一个可以通过该checkError
方法测试的内部标志。
JVM 以这种方式处理 SIGPIPE 的原因是什么?
上面解释了正在发生的事情。“为什么”是......我猜......设计人员希望使其PrintStream
易于用于调用者不想在每次调用中处理可能的典型用例。System.out
IOException
不幸的是,没有优雅的解决方案:
- 你可以打电话给
checkError
...
- 您应该能够获取该
FileDescriptor.out
对象,并将其包装在一个新FileOutputStream
对象中......并使用它而不是System.out
.
请注意,没有强有力的保证 Java 应用程序只会将 10 行输出写入java foo | head -1
. 应用程序很可能会提前写很多行,并且只有head
在读取前 10 行之后才“看到”管道关闭。这适用于System.out
(and checkError
) 或 wrap FileDescriptor
。