studio programacion móviles libros libro desarrollo desarrollar curso aprende aplicaciones java buffer inputstream outputstream

java - programacion - ¿Por qué es bueno cerrar() una corriente de entrada?



manual de programacion android pdf (4)

Tengo una experiencia de sonido en el lenguaje de programación Java. Pero una cosa que siempre he tenido en mente es que ¿por qué es necesario close() java.io.InputStream o sus subclases?

Ahora, con java.io.OutputStream , digamos FileOutputStream , después de escribir en un archivo, si no close() la secuencia de salida, los datos que pretendíamos escribir en el archivo permanecen en el búfer y no se escriben en el archivo. .

Por lo tanto, es necesario close() un OutputStream . Pero nunca tuve experiencias amargas después de no cerrar un InputStream .

Pero aún así, todos los artículos en Internet y en los libros dicen que siempre es bueno cerrar cualquier Transmisión, ya sea un InputStream o un OutputStream .

Entonces, mi pregunta es ¿por qué es necesario close() un InputStream ? La gente dice que es posible que se enfrente a una pérdida de memoria si no la close() . Entonces, ¿qué tipo de pérdida de memoria es eso?


Es una potencial fuga de recursos. La herencia hace que sea imposible saber exactamente qué recurso se podría filtrar cuando se hace la pregunta de esta manera. Por ejemplo, podría escribir mi propia clase llamada VoidInputStream que no asigna recursos que requieran el cierre. Pero aún así, si no lo cierra, está violando el contrato heredado.

Consulte http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html obtener una lista de los diferentes flujos de entrada.

La prueba de los recursos filtrados es muy difícil. En segundo lugar solamente a la prueba de problemas de concurrencia. No esté tan seguro de que, sin saberlo, no ha causado un pequeño caos.


No es una pérdida de memoria tanto como una pérdida de manejador de archivos. El sistema operativo solo permitirá que un solo proceso abra una cierta cantidad de archivos, y si no cierra sus flujos de entrada, podría impedir que la JVM se abra más.


Puede haber cualquier número de recursos del sistema operativo asociados con un InputStream, como archivos abiertos o Sockets. Un cierre () liberará estos recursos.

Su programa no necesita saber con qué tipo de InputStream está trabajando. Simplemente debe cumplir con el contrato que el flujo se cierra después de su uso, de modo que se puedan liberar los recursos.


Un InputStream vincula un pequeño recurso del kernel, un manejador de archivos de bajo nivel. Además, el archivo se bloqueará en cierta medida (desde eliminar, cambiar de nombre), siempre que lo tenga abierto para leer. Imaginemos que no te importó el archivo bloqueado. Eventualmente, si necesita leer otro archivo y abrirlo con un nuevo InputStream, el kernel asigna secuencialmente un nuevo descriptor (flujo de archivos) para usted. Esto se sumará.

Es solo una cuestión de tiempo hasta que el programa falla para una aplicación de larga ejecución.

La tabla de descriptores de archivos para un procesador es de tamaño limitado. Finalmente, la tabla de manejador de archivos se quedará sin ranuras libres para el proceso. Incluso en los miles, aún puede agotar esto fácilmente para una aplicación de larga ejecución, en cuyo momento, su programa ya no puede abrir un nuevo archivo o socket.

La tabla del descriptor de archivos de proceso es tan simplista como algo así como:

IOHANDLE fds[2048]; // varies based on runtime, IO library, etc.

Comienzas con 3 ranuras ocupadas. Rellena eso y has realizado una denegación de servicio en ti mismo.

Así que todo eso es bueno saber; ¿Cuál es la mejor manera de aplicarlo?

Si confía en que los objetos locales salgan del alcance, entonces depende del recolector de basura, que puede obtenerlo en su propio momento dulce (no determinístico). Así que no confíe en el GC, ciérrelos explícitamente.

Con Java, usted desea usar try-with-resources en tipos que implementan java.lang.AutoCloseable ", que incluye todos los objetos que implementan java.io.Closeable" según los documentos: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Con C #, el equivalente es un bloque "utilizando" en objetos que implementan IDisposable