Java 没有在SIGPIPE上杀死JVM
JVM以这种方式处理SIGPIPE的原因是什么 我早就料到了Java 没有在SIGPIPE上杀死JVM,java,jvm,signals,sigpipe,Java,Jvm,Signals,Sigpipe,JVM以这种方式处理SIGPIPE的原因是什么 我早就料到了 javafoo | head-10 与 公共类Foo{ 公共静态void main(字符串[]args){ Stream.iterate(0,n->n+1).forEach(System.out::println); } } 在写入第11行时导致进程终止,但情况并非如此。相反,似乎在PrintStream上只设置了一个故障标志,可以通过System.out.checkError()检查,结果是SIGPIPE异常导致IOExcept
javafoo | head-10
与
公共类Foo{
公共静态void main(字符串[]args){
Stream.iterate(0,n->n+1).forEach(System.out::println);
}
}
在写入第11行时导致进程终止,但情况并非如此。相反,似乎在PrintStream上只设置了一个
故障
标志,可以通过System.out.checkError()
检查,结果是SIGPIPE异常导致IOException
对于大多数OutputStream
和Writer
类,此异常通过“write”方法传播,必须由调用方处理
但是,当您写入System.out时,您使用的是一个PrintStream
,该类按设计负责处理您的IOException
。正如javadoc所说:
PrintStream
为另一个输出流添加了功能,即能够方便地打印各种数据值的表示。还提供了另外两个特性。与其他输出流不同,PrintStream
从不抛出IOException
;相反,异常情况只是设置了一个内部标志,可以通过checkError
方法进行测试
JVM以这种方式处理SIGPIPE的原因是什么
以上解释了正在发生的事情。“为什么”是。。。我想。。。设计者希望使PrintStream
易于用于System.out
的典型用例,调用方不希望在每次调用时处理可能的IOException
不幸的是,没有优雅的解决方案:
- 您可以直接调用
checkError
- 您应该能够获得
对象,并将其包装到一个新的FileDescriptor.out
对象中。。。并用它代替FileOutputStream
System.out
请注意,Java应用程序在
JavaFoo | head-1
中只能写入10行输出,这一点并没有强有力的保证。应用程序很可能会提前写很多行,并且只有在head
开始阅读前10行之后才能“看到”关闭的管道。这适用于System.out
(和checkError
),或者如果包装FileDescriptor
,,则会发生SIGPIPE异常导致IOException
对于大多数OutputStream
和Writer
类,此异常通过“write”方法传播,必须由调用方处理
但是,当您写入System.out时,您使用的是一个PrintStream
,该类按设计负责处理您的IOException
。正如javadoc所说:
PrintStream
为另一个输出流添加了功能,即能够方便地打印各种数据值的表示。还提供了另外两个特性。与其他输出流不同,PrintStream
从不抛出IOException
;相反,异常情况只是设置了一个内部标志,可以通过checkError
方法进行测试
JVM以这种方式处理SIGPIPE的原因是什么
以上解释了正在发生的事情。“为什么”是。。。我想。。。设计者希望使PrintStream
易于用于System.out
的典型用例,调用方不希望在每次调用时处理可能的IOException
不幸的是,没有优雅的解决方案:
- 您可以直接调用
checkError
- 您应该能够获得
对象,并将其包装到一个新的FileDescriptor.out
对象中。。。并用它代替FileOutputStream
System.out
请注意,Java应用程序在
JavaFoo | head-1
中只能写入10行输出,这一点并没有强有力的保证。应用程序很可能会提前写很多行,并且只有在head
开始阅读前10行之后才能“看到”关闭的管道。这适用于System.out
(和checkError
)或如果您包装FileDescriptor
,谢谢您的回答。这种推理是有道理的。。在大多数用例中,每当管道出现问题时,处理IOException可能会很烦人。使用FileDescriptor
的方法似乎是一种优雅的方法,如果您喜欢这种行为,请告诉我它是否有效。我还没试过。我通过查看系统
类中发生的事情来了解它。。。我可能弄错了。(我>>认为当你想写stdout时,你需要FileDescriptor.out
。一般来说,PrintStream
是一个可怕的错误设计,但与其他Java 1.0错误不同,它没有被弃用,因为它在系统.out
字段中的突出位置。这似乎是可能的,是的。我想最好是这样被包装在自定义打印流中,然后在IOException中退出。@leyrenPrintStream
是OutputStream
的子类型,混淆了字节流和字符流的概念。类似的错误设计的类,例如LineNumberInputStream
和StringBufferInputStream
,已被弃用。as说,PrintStream
由于兼容性问题,PrintWriter
没有被替换,因为System.out
无法更改。但即使是替换者也有吞咽异常的可怕行为,只告诉发生了异常(一个布尔值)