2011-08-17 17 views
19

No pude encontrar una aclaración de esto en la documentación. Pero cuando tenemos un objeto Process y llamamos getInputStream(),Cierre correcto del proceso Java InputStream de getInputStream

qué obtenemos una nueva corriente que debemos cierre de forma explícita cuando hayamos terminado con ella? o ¿obtenemos la transmisión que ya está allí, asociada con el Proceso, que no deberíamos cerrar, pero el Proceso se encargaría de cerrarla?

Básicamente, ¿cómo debemos interactuar con la corriente que obtenemos de Process.getInputStream()? cerrar o no cerrar?

Respuesta

8

Mis primeras reacciones fue a cerrarla, siempre cercanos corrientes que abra. Me doy cuenta de que la documentación no está a la altura, pero como no indican explícitamente no cierren que para mí significa seguir buenas prácticas de programación.

InputStream is = process.getInputStream() 
try { 
    // your code 
} finally { 
    try { is.close(); } catch (Exception ignore) {} 
} 

Si tiene que asegurarse de que esto no es problemático, acaba de escribir un caso de prueba rápida donde estupendo desde la entrada de transmitir un par de docenas de veces, cada abertura de tiempo y el cierre de la InputStream.

+3

IOUtils.closeQuietly (is) se encargará de try {is.close(); } catch (Exception ignore) {} – Kirby

5

Cuando llama al Process.getInputStream(), obtiene un flujo de entrada existente que se configuró para el proceso. Cuando el proceso muere, esa corriente de entrada hace no desaparece automáticamente, considérelo como un búfer del que todavía puede leer. El final del tubo del proceso puede estar cerrado, pero su final no. Es su responsabilidad cerrarlo, aunque GC eventualmente lo obtendrá.

También debe cerrar los otros dos: getErrorStream() y getOutputStream().

+0

"Cuando el proceso muere, la corriente de entrada no desaparece automáticamente": cuando se inicia un proceso, Java ejecuta el subproceso "process reaper", que cierra el lado local de tales pipes en este caso. –

0

o qué obtenemos la corriente que ya está ahí, asociados con el proceso , que no debería cerrarse, pero el proceso se haría cargo de de cerrarla?

No hay Javadoc que lo diga, ¿verdad?

2

De la lectura de UNIXProcess.java, esto es lo que sucede:

es necesario distinguir entre dos estados: o proceso está todavía vivo o está muerto.

Si el proceso está vivo, mediante el cierre de OutputStream (va a la entrada estándar del proceso), le está diciendo al proceso que ya no hay 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 se extingue, Java almacenará en búfer los datos restantes de stdout/stderr, y cerrará los tres flujos (se está ejecutando el subproceso "proceso de reaper", que se notifica en el proceso de muerte). Cualquier intento de escribir en OutputStream fallará. La lectura desde InputStream arrojará datos almacenados en el búfer, si los hay. Cerrar cualquiera de ellos no tiene ningún beneficio, pero tampoco causa ningún daño. (Los descriptores de archivos subyacentes están cerrados en este momento).

0

No cierra transmisiones, que no abrió, es un efecto secundario desagradable. Si creaste el proceso, mátalo primero y luego cierra las transmisiones.