En pseudocódigo, esto es lo que estoy haciendo:Process.waitFor(), hilos y InputStreams
Process proc = runtime.exec(command);
processOutputStreamInThread(proc.getInputStream());
processOutputStreamInThread(proc.getErrorStream());
proc.waitFor()
Sin embargo, a veces processOutputStreamInThread
no se ve ninguna salida y, a veces lo hace. Aproximadamente, el método crea un BufferedInputStream
de la salida del comando y lo envía a un registrador.
Sobre la base de lo que estoy viendo, supongo que command
no necesita tener todo esto es la salida vierten en los arroyos alimentados por getInputStream()
y getErrorStream()
, permitiendo así que la corriente esté vacío.
Los resultados de mis pruebas son las siguientes preguntas:
(1) ¿Se waitFor()
en java.lang.Process requieren la salida del programa ejecutado ha sido leído antes de que vuelva?
La documentación sólo se afirma:
hace que el hilo actual que esperar, si es necesario, hasta que el proceso representado por este objeto
Process
ha terminado. Este método regresa inmediatamente si el subproceso ya ha finalizado. Si el subproceso aún no ha terminado, la cadena de llamada será bloqueada hasta que el subproceso finalice.
(2) ¿En qué condiciones las corrientes proporcionadas por getInputStream
y getErrorStream
deben ser cerradas y/o son cerrados de forma automática?
La documentación sólo se afirma:
Obtiene el flujo de error del subproceso. La secuencia obtiene datos transmitidos desde la secuencia de salida de error del proceso representado por este objeto de proceso.
Nota de implementación: es una buena idea que el flujo de entrada se almacene en el búfer.
Una user reports que tuvo que cerrar el mismo arroyos, pero me da una excepción al menos una parte del tiempo que indica que la corriente ya está cerrado cuando intento hacerlo.
Editar: cambió getOutputStream
-getInputStream
, ahora presente anteriormente.
Resolución: El problema terminó siendo que, en ciertos casos, los hilos utilizados para procesar la secuencia de salida no se ejecutarían hasta que se completara mi proceso de corta duración, lo que daría como resultado que la corriente de entrada no me proporcionara datos. waitFor
no esperó la salida del programa ejecutado. Más bien, el programa se ejecutó y finalizó antes de que se pudiera recopilar cualquier resultado.
que utilizan hilos porque no estoy seguro de cuánto de salida que iba a conseguir en el error estándar y la salida estándar y que quería ser capaz de procesar ambos a la vez, sin bloquear uno o el otro debe sólo uno de ellos tiene datos disponibles. Pero, como mis hilos no pueden leer de forma consistente la salida del programa ejecutado, no es una solución.
Mis Coded finales parecían algo como esto:
ProcessBuilder pb = new ProcessBuilder(cmdargs);
pb.redirectErrorStream(true);
Process proc = pb.start();
processOutputStream(proc.getInputStream());
proc.waitFor()
¿Deben cerrarse también las otras corrientes si se usan? ¿Están implícitamente cerrados cuando el proceso termina? –
@Kaleb He agregado una respuesta a tu pregunta a mi publicación. –
En cuanto al artículo de JavaWorld, hay un error con la solución final. Si un proceso finaliza muy rápidamente, es posible que errorGobbler y outputGobbler aún no hayan ejecutado y consumido datos. El código debe ser: proc.waitFor(); errorGobbler.join(); outputGobbler.join() ;. Esto obligó al hilo principal a esperar hasta que las secuencias terminen de leer la entrada. –