2010-07-12 12 views
11

Estoy creando un método Java que acepta un único InputStream como argumento. Para la comodidad de trabajar con una corriente basada en caracteres, envuelvo el InputStream proporcionado en el inicio de la implementación del método de la siguiente manera:¿Cómo evito cerrar un InputStream pasado a mi método que envuelvo en las transmisiones de Reader?

public void doStuff(InputStream inStream) { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); 
    ... 
} 

Desde el InputStream (inStream) se pasa a mi método, no lo creo quiero cerrarlo ... ya que creo que esa debería ser la responsabilidad del cliente que llama a mi método (¿es correcta esta suposición?). Sin embargo, creo que debería cerrar el BufferedReader que creé; pero al hacerlo, creo que cerrará automáticamente todas las otras secuencias compuestas, incluido el inStream.

¿Alguien ve una manera de cerrar el BufferedReader y el InputStreamReader que creé sin cerrar el InputStream pasado a mi método? Tal vez hay una manera de hacer una copia de la proporcionada InputStream antes de envolverlo? Gracias

+1

¿Sabía que la transmisión no envuelta será prácticamente inútil? –

+1

Debe suministrar un 'Charset' específico al crear un' InputStreamReader' en lugar de ignorarlo y dejar que se use la plataforma predeterminada. – ColinD

+0

Tom, ¿podrías aclarar a qué te refieres con "la transmisión desenvuelta será bastante inútil"? – user389591

Respuesta

3

Lo que iba a tratar serían reemplazando el método close:

BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)){ 
    public void close() throws IOException { 
     synchronized (lock) { 
      if (in == null) 
       return; 
     } 
    } 
}; 
// rest of your code 

un poco loco, pero debería funcionar. Sin embargo, no estoy seguro de que este sea el mejor enfoque.

Creo que esta es una pregunta interesante, por lo que espero que alguien experto dé su opinión.

4

Personalmente me gustaría simplemente evitar el problema cambiando la firma de su método para requerir que un BufferedReader (o lector) pueden pasar en.

+0

Esto propaga la creación del BufferedReader a la persona que llama. Pero, ¿y si el método de llamada también recibe su transmisión de otro lugar? –

+1

Tiene un buen punto: también es posible que desee proporcionar una versión basada en "Reader". Porque, si alguien obtiene un 'InputStream' con una codificación no predeterminada, no puede usar el método basado en la transmisión, porque el InputStreamReader utiliza la codificación incorrecta. –

+0

La clase 'java.util.Properties' proporciona los métodos' load (InputStream inStream) 'y' load (Reader reader) '. Creo que tener ambas opciones disponibles para posibles clientes de su clase es una conveniencia que puede simplificar el código del cliente. Es decir, el cliente no tiene que envolver un 'InputStream' para obtener un' Reader' antes de pasarlo como un argumento para el método. – user389591

9

No es necesario cerrar un BufferedReader o InputStreamReader o probablemente la mayoría de las implementaciones de los lectores , cuando no desea cerrar el lector subyacente.

Estos lectores no ser titular de los recursos que una llamada a close() haría libre y el que el recolector de basura no tendría libre de todos modos (por ejemplo, recursos o valores de las variables estáticas nativos) cuando se le cae la referencia para el lector al final de tu método.

Las secuencias de entrada subyacentes que se comunican con recursos nativos, p. FileInputStream o secuencias obtenidas de URL, se deben cerrar para liberar esos recursos nativos.

Para Writer, hay una diferencia en que close() generalmente llama a flush(). Pero luego, puede llamar al flush() directamente.

+1

Sí, aunque algunos flujos de compresión (aunque no 'Readers', hasta donde yo sé) usan recursos nativos y deben cerrarse. –

+0

De hecho. Entonces, cuando quería concatenar varias secuencias de salida, cada una comprimida por sí misma, en una secuencia de salida, una opción es anular el método de cierre como lo sugiere @Cristian C. (Algo similar probablemente ocurre cuando se usan archivos comprimidos que contienen varios archivos). –

Cuestiones relacionadas