Tengo una sólida experiencia en lenguaje de programación Java. Pero una cosa que siempre ha estado en mi mente es ¿por qué es necesario close() java.io.InputStream o sus subclases?

Ahora con java.io.OutputStream, decir FileOutputStream, después de escribir a un archivo, si no nos close() el flujo de salida, los datos que tenemos la intención de escribir en el archivo permanece en el buffer y no se escriben en el archivo.

Por lo que se hace necesario close() un OutputStream. Pero yo nunca había tenido experiencias amargas después de no de cierre un InputStream.

Pero todavía todos los artículos en internet y libros dicen que siempre es bueno cerrar cualquier Secuencia puede ser un InputStream o un OutputStream.

Así que mi pregunta es que ¿por qué no es necesario close() un InputStream? La gente dice que se puede enfrentar una pérdida de memoria de no close() ella. Entonces, ¿qué tipo de pérdida de memoria es eso?

  • recursos fuga es probablemente más de un motivo de preocupación. Manejo de inputstream requiere del sistema operativo para el uso de sus recursos y si no libre una vez que usted use, se le agote los recursos.
  • En algunos Jvm, en el núcleo se mantenga una FIS abierto (como a mi entender es) hasta que: a) el cierre de la secuencia, o B) la JVM salidas. Otros flujos (especialmente cuando se trata con sockets) dejar que otras cosas saber cuando está hecho. Por ejemplo, cuando se cierra una OutStream de un Socket, el correspondiente inputstream en el otro lado de la internet se cierra demasiado.
  • No. No corrientes se cierre automáticamente. Usted tiene a cerca de sí mismo.
  • Usted no tiene que cerrar para todas las subclases. Por ejemplo, un java.io.ByteArrayInputStream no utiliza ningún tipo de descriptores de archivo, y por lo tanto, el cierre es un no-op, consulte docs.oracle.com/javase/8/docs/api/java/io/…
InformationsquelleAutor Aditya Singh | 2014-10-24

4 Comentarios

  1. 40

    Un InputStream lazos de hasta un pequeño núcleo de recursos, un bajo nivel de identificador de archivo. Además, el archivo será bloqueado hasta cierto punto (de borrar, cambiar de nombre), siempre y cuando usted tiene que abrir para leer. Vamos a imaginar que no te importaba el archivo bloqueado. Finalmente, si usted necesita leer otro archivo y abrirlo con un nuevo InputStream, el kernel de forma secuencial asigna un nuevo descriptor (secuencia de archivo) para usted. Esto le suman.

    Es sólo una cuestión de tiempo hasta que un error en el programa por un tiempo la ejecución de la aplicación.

    El archivo descriptor de la tabla para que el procesador es de tamaño limitado. Finalmente, la tabla de identificador de archivo se ejecute fuera de las ranuras libres para el proceso. Incluso en los miles, usted todavía puede agotar fácilmente esto por mucho la ejecución de la aplicación, momento en el cual, el programa no puede abrir un archivo nuevo o socket.

    El proceso de archivo de la tabla de descriptores es tan simplista como algo como:

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

    De empezar con 3 ranuras ocupadas. Llenarla y de haber realizado un ataque de denegación de servicio en sí mismo.

    Así que todo eso es bueno saber; cómo se aplica?

    Si usted confía en el local de los objetos de alcance, entonces su hasta el Recolector de Basura, lo que puede redundar en su propio tiempo dulce (no determinista). Así que no confíe en el GC, cerca de ellos explícitamente.

    Con Java, desea utilizar try-con-recursos en los tipos que implementan en java.lang.AutoCloseable», que incluye todos los objetos que implementan en java.io.Closeable» por el docs: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

    Con C#, el equivalente es un «uso» de los bloques en los objetos que implementa IDisposable

    • Es cerrado cuando si es variable local y método devuelve? Por supuesto, asumiendo que sólo se han utilizado ClassPathResource de la primavera.
    • Usted necesitará utilizar try-con-recursos para asegurar que, de lo contrario, su hasta el Recolector de Basura como para cuando va a recoger (no determinista). docs.oracle.com/javase/tutorial/essential/exceptions/…, el Mismo se aplica en C#, pero tendría que utilizar la instrucción using.
  2. 7

    No es un memoria de fugas tanto como un identificador de archivo de fugas. El sistema operativo sólo permitirá un único proceso para abrir un cierto número de archivos, y si usted no cierre los flujos de entrada, se puede prohibir la JVM de la apertura de más.

    • Estoy hablando de un InputStream en general. Y no sólo un FileInputStream.
    • Su ejemplo original con OutputStream utiliza un FileOutputStream para ilustrar por qué tiene que ser cerrado, así que, ¿por qué este ser menos válida ejemplo? 🙂
    • No, coz que era para hacerte entender mi pregunta. Pero esta respuesta es específica para un FileInputStream. Mientras mi pregunta es para un InputStream en general. 🙂
    • Así es la respuesta. La mayoría de las corrientes en última instancia consumir un FD n el kernel. Si en lo que se refiere a un archivo, un socket, o algo más, es completamente irrelevante.
    • ¿Qué hace un FD representan?
    • Es sinónimo de ‘descriptor de archivo’, pero es un término general en el kernel que se usa también para sockets, puertos de comunicaciones, …

  3. 4

    Es una potencial pérdida de recursos. La herencia hace que sea imposible saber exactamente qué recursos podría ser filtrado cuando se hace la pregunta de esta manera. Por ejemplo, yo podría escribir mi propia clase llamada VoidInputStream que asigna los recursos que requieren de cierre. Pero aún si no se cierra se está violando el heredado del contrato.

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

    Pruebas para el filtrado de los recursos es muy difícil. En segundo lugar solamente a las pruebas para detectar problemas de concurrencia. No esté tan seguro de que no, sin saberlo, causó un poco de caos.

  4. 3

    Podría ser cualquier número de recursos del sistema operativo asociado con un InputStream, como abrir archivos, o Sockets. Un close() se libre de estos recursos.

    El programa no necesita saber qué tipo de InputStream con los que trabaja. No sólo debe adherirse al contrato que la corriente está cerrado después de su uso, por lo que los recursos pueden ser liberados.

Dejar respuesta

Please enter your comment!
Please enter your name here