example - Cerrar correctamente Java Process InputStream desde getInputStream
getinputstream java ejemplo (6)
No pude encontrar una aclaración de esto en la documentación. Pero cuando tenemos un objeto de Process
y llamamos a getInputStream()
,
¿Obtenemos un nuevo flujo que deberíamos cerrar explícitamente cuando terminemos con él? ¿O obtenemos el flujo que ya está allí, asociado con el Proceso, que no deberíamos cerrar, pero el Proceso se encargaría de cerrarlo?
Básicamente, ¿cómo debemos interactuar con el flujo que obtenemos de Process.getInputStream()
? ¿Cerrar o no cerrar?
¿O obtenemos el flujo que ya está allí, asociado con el Proceso, que no deberíamos cerrar, pero el Proceso se encargaría de cerrarlo?
No hay un Javadoc que lo diga, ¿verdad?
Cuando llama a Process.getInputStream()
, obtiene un flujo de entrada existente que se configuró para el proceso. Cuando el proceso muere, el flujo de entrada no desaparece automáticamente; piense en él como un búfer del que aún puede leer. El final del proceso de la tubería podría estar cerrado, pero su final no lo está. Es su responsabilidad cerrarlo, aunque GC eventualmente lo obtendrá.
También debe cerrar los otros dos: getErrorStream()
y getOutputStream()
.
De leer UNIXProcess.java, esto es lo que sucede:
Necesitamos distinguir entre dos estados: cualquiera de los procesos está todavía vivo o está muerto.
Si el proceso está vivo, al cerrar OutputStream (va a la entrada estándar del proceso), le está diciendo al proceso que no hay más entrada para él. Al cerrar InputStreams (stdout, stderr del proceso), el proceso ya no es escribir en ellos (obtendrá SIGPIPE si lo intenta).
Cuando el proceso muera, Java almacenará en búfer los datos restantes de stdout / stderr, y cerrará los tres flujos por usted (está ejecutando el hilo del "reaper de proceso", que se notifica en el proceso de muerte). Cualquier intento de escribir en OutputStream fallará. La lectura de InputStream devolverá datos almacenados en búfer, si los hay. Cerrar cualquiera de ellos no tiene ningún beneficio, pero tampoco causa daño. (Los descriptores de archivos subyacentes están cerrados en este momento).
Mi primera reacción fue cerrarla, siempre cierras las secuencias que abres. Me doy cuenta de que la documentación no está a la par, pero como no declaran explícitamente que no se me cierre eso significa seguir buenas prácticas de programación.
InputStream is = process.getInputStream()
try {
// your code
} finally {
try { is.close(); } catch (Exception ignore) {}
}
Si necesita asegurarse de que esto no sea problemático, simplemente escriba un caso de prueba rápida en el que sea excelente desde el flujo de entrada unas docenas de veces, cada vez que abra y cierre InputStream.
No cierra las transmisiones que no abrió, es un efecto secundario desagradable. Si creó el proceso, elimínelo primero y cierre las secuencias después de eso.
Yo siempre los cierro! No estoy 100% seguro, pero por lo que sé, si deja abierta la corriente de entrada, el archivo se abrirá hasta que lo cierre. Así que sigue las "reglas estándar" y ciérralo! siga un ejemplo: problema de WaitFor () de Process Builder y limitaciones de archivos abiertos