¿Cómo hago para que Java salga cuando se conecta a la cabeza?

Tengo un proceso java que imprime mucho texto. A veces solo quiero ver un poco del texto. Con programas normales solo puedo hacer:

$ myprog | head

Solo veré 10 líneas de salida de myprog y saldrá inmediatamente. Pero con java, si lo hago:

$ java MyClass | head

Obtengo las primeras 10 líneas de salida, pero el proceso de Java no se cerrará hasta que haya terminado con todo su procesamiento. Es como si a Java no le importara que stdout (System.out) se haya ido y que el proceso principal esté muerto y desaparecido.

Todos los demás programas salen en silencio, como cat:

$ 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:

O salga con un error/excepción de tubería rota, como 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

¿Cómo puede hacer que Java genere una excepción al llamar a System.out.println() cuando canalizo la salida a algo como head? Me encantaría poder hacer algo como:

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

preguntado el 27 de julio de 12 a las 21:07

SIGPIPE se envía al proceso de Java en este caso, pero no estoy seguro de qué hace Java con él. Si pudiera comprobar si la JVM ha recibido un sigpipe y muere, debería funcionar. -

Java hace cosas especiales con las señales y sé por otros problemas que es casi imposible configurar un programa Java para atrapar señales. -

2 Respuestas

Estoy usando checkError()

De PrintStream-API-Docu:

A diferencia de otros flujos de salida, un PrintStream nunca lanza una IOException; en cambio, las situaciones excepcionales simplemente establecen un indicador interno que se puede probar a través del método checkError.

así que intenta algo como esto:

        while(!System.out.checkError()) {
            System.out.println("hi");
        }

respondido 16 nov., 12:22

Gracias por los avisos sobre los documentos. Había estado buscando por todas partes algo así, pero por alguna razón pasé por alto la descripción del nivel superior. Eso es súper molesto, y parece que sería ineficiente llamar a checkError cada vez en lugar de solo intentar atrapar. - solo ninguno

Si no te gusta el .checkError() método de la respuesta de sascha y preferiría recibir excepciones que puede usar

OutputStream stream = new FileOutputStream(FileDescriptor.out);

Pierdes el PrintStream funciones específicas. En mi caso, no eran relevantes y este enfoque fue más fácil que construir un montón de cheques piratas.

Tenga en cuenta que esto no se comportará si ha redirigido el System.out vía System.setOut, ya que FileDescriptor.out apuntará al descriptor de salida original, no al descriptor redirigido.

contestado el 23 de mayo de 17 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.