2010-09-02 23 views
44

Me preguntaba si es necesario cerrar el InputStream después de cerrar el lector?¿Debo cerrar InputStream después de cerrar el Reader

try { 
     inputStream = new java.io.FileInputStream(file); 
     reader = new InputStreamReader(inputStream, Charset.forName("UTF-8")); 
    } 
    catch (Exception exp) { 
     log.error(null, exp); 
    } 
    finally { 
     if (false == close(reader)) { 
      return null; 
     } 
     // Do I need to close inputStream as well? 
     if (false == close(inputStream)) { 
      return null; 
     } 
    } 
+23

Utilice 'if (!close (lector) 'y no' if (falso == cerrar (lector)) ' –

+4

@Jacob Tomaw - ¿POR QUÉ? Tengo una vista muy pobre. "falso" ocupa más espacio de pantalla que "!". Esto al menos me hará más legible. –

+9

@Yan Cheng CHEOK es un estilo pobre, y mucho más difícil de leer para la próxima persona que lea su código. Si tiene problemas para ver el!, Necesita aumentar el tamaño de fuente de su computadora u obtener lentes más fuertes, no crear su propia convención de codificación. – bwawok

Respuesta

41

No, usted no tiene que hacerlo.

Dado que el enfoque de decorador utilizado para las transmisiones en Java puede generar nuevas transmisiones o lectores adjuntándolos a otros, esto se realizará automáticamente mediante la implementación InputStreamReader.

Si nos fijamos en su fuente InputStreamReader.java se ve que:

private final StreamDecoder sd; 

public InputStreamReader(InputStream in) { 
    ... 
    sd = StreamDecoder.forInputStreamReader(in, this, (String)null); 
    ... 
} 

public void close() throws IOException { 
    sd.close(); 
} 

Así que la operación de cierre cierra la realidad que subyace InputStream el lector corriente.

EDITAR: Quiero estar seguro de que StreamDecoder cerrar también funciona en el flujo de entrada, estad atentos.

lo comprobó, en StreamDecoder.java

void implClose() throws IOException { 
    if (ch != null) 
    ch.close(); 
    else 
    in.close(); 
} 

que se llama cuando el cierre del sd se llama.

+0

Y el código para cada uno de los StreamDecoders concretos también cierra la línea de entrada subyacente donde se invoca sd.close() ;-) – helios

+0

¿Hace algún daño si cierro el inputStream? –

+2

¿Lo encontró explícitamente escrito en la documentación? No estoy seguro de que sea una restricción para todas las implementaciones de Java. @Yan Cheng CHEOK: Si cierra el flujo de entrada después de cerrar el lector, no hace daño. –

3

No, no es que el lector se cerrará el InputStream subyacente

0

Acordding a la fuente sniffing el lector cierra su inputstream subyacente. Según javadoc, ve que InputStreamReader "cierra la secuencia" cuando se invoca reader.close().

No estoy seguro de si ANY Reader debe cerrar sus fuentes cuando lo haga reader.close(). Creo que esto es importante para que tu código pueda usar un lector sin importar qué tipo concreto sea.

De todos modos, tiene sentido que se cumpla.

5

No es necesario cerrar la transmisión si el lector es close().

Cierra la secuencia y libera los recursos del sistema asociados con . Una vez que la secuencia se ha cerrado, las invocaciones read(), ready(), mark(), reset() o skip() arrojarán una IOException. Cerrar una secuencia previamente cerrada no tiene ningún efecto.

+0

Enlace reformateado; por favor revertir si es incorrecto. – trashgod

8

Técnicamente, cerrando el Reader se cerrará el InputStream. Sin embargo, si hubo una falla entre la apertura del InputStream y la creación del Reader, aún debe cerrar el InputStream. Si cierra el InputStream [el recurso], no debería haber una buena razón para cerrar el Reader [el decorador]. También hay errores populares donde cerrar un decorador puede arrojar una excepción antes de cerrar el decorado. Por lo tanto:

Resource resource = acquire(); 
try { 
    Decorator decorated = decorate(resource); 
    use(decorated); 
} finally { 
    resource.release(); 
} 

Hay algunas complicaciones a tener en cuenta. Algunos decoradores pueden contener recursos nativos debido a su implementación. Por lo general, los decoradores de salida deben lavarse, pero solo en el caso feliz (por lo tanto, en el try no en el bloque finally).

+2

Esto falla si 'Decorator' es, por ejemplo, un' BufferedWriter'. No está documentado explícitamente en ninguna parte que un programador deba llamar explícitamente 'flush()' después de su uso. – BalusC

+0

@BalusC Estoy confundido. La primera línea de los documentos de la API 'BufferedWriter' dice que almacena en búfer los caracteres. –

+0

'BufferedWriter' (decorado)' flush() 'en' close() '. El 'FileWriter' (recurso), por ejemplo, no hace eso. Por lo tanto, arriesgas los caracteres desaparecidos cuando cierras solo el 'FileWriter' – BalusC

Cuestiones relacionadas