如何在管道输入时让java退出

onl*_*one 17 java exception pipe unix-head

我有一个java进程打印出很多文本.有时我只是想看一些文字.使用普通程序,我可以这样做:

$ myprog | head
Run Code Online (Sandbox Code Playgroud)

我只会看到myprog的10行输出,它会立即退出.但是对于java,如果我这样做:

$ java MyClass | head
Run Code Online (Sandbox Code Playgroud)

我获得了前10行输出,但java进程在完成所有处理之前不会退出.这就像java并不关心stdout(System.out)已经消失,而且头部进程已经死了.

所有其他程序要么像猫一样默默地退出:

$ cat /etc/group | head
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:
Run Code Online (Sandbox Code Playgroud)

或者退出管道错误/异常,如python:

$ python -c 'while True: print "hi"' | head
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
Traceback (most recent call last):
  File "<string>", line 1, in <module>
IOError: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)

当我将输出管道输出到像head这样的东西时,如何在调用System.out.println()时让java引发异常?我希望能够做到这样的事情:

try {
    while(true) {
        System.out.println("hi");
    }
} catch(BrokenPipeException e) {
    // exit gracefully
}
Run Code Online (Sandbox Code Playgroud)

Sas*_*cha 11

我正在使用 checkError()

来自PrintStream-API-Docu:

与其他输出流不同,PrintStream永远不会抛出IOException; 相反,异常情况只是设置一个内部标志,可以通过checkError方法进行测试.

所以尝试这样的事情:

        while(!System.out.checkError()) {
            System.out.println("hi");
        }
Run Code Online (Sandbox Code Playgroud)


Mic*_*son 1

如果您不喜欢Sascha 答案.checkError()中的方法并且宁愿接收异常,您可以使用

OutputStream stream = new FileOutputStream(FileDescriptor.out);
Run Code Online (Sandbox Code Playgroud)

你失去了PrintStream特定的功能。就我而言,它们并不相关,而且这种方法比构建一堆黑客检查更容易。

System.out请注意,如果您重定向了via ,则这不会起作用System.setOut,因为FileDescriptor.out它将指向原始输出描述符,而不是重定向的输出描述符。