2009-09-07 13 views
152

estoy leyendo un archivo local utilizando un BufferedReader envuelto alrededor de un FileReader:¿Debo cerrar() tanto FileReader como BufferedReader?

BufferedReader reader = new BufferedReader(new FileReader(fileName)); 
// read the file 
// (error handling snipped) 
reader.close(); 

¿Es necesario close() la FileReader así, o se la envoltura manejar eso? que he visto código donde la gente hace algo como esto:

FileReader fReader = new FileReader(fileName); 
BufferedReader bReader = new BufferedReader(fReader); 
// read the file 
// (error handling snipped) 
bReader.close(); 
fReader.close(); 

Este método es llamado desde un servlet, y me gustaría para asegurarse de que no dejo los identificadores abiertos.

+4

Ya sabes, puedes leer la fuente de información como esta. Está todo allí en src.zip en el directorio de instalación de JDK, o puede leerlo en línea en, por ejemplo, http://www.docjar.com/html/api/java/io/BufferedReader.java.html – gustafc

+36

Diciéndole a alguien que lea la fuente es peor que decir "¡RTFM!". Y qué pasa si la fuente tiene un error; implícitamente, ¿queremos saber cuál es el comportamiento * correcto *? – Raedwald

+1

Bueno ... desde este punto de vista: apuntando a las especificaciones API no es mejor que. Si la fuente no tiene un error que cause que no se comporte como se especifica en los documentos, no puede confiar en los documentos. Entonces, no hay una buena manera de responder a esa pregunta. – Atmocreations

Respuesta

179

no.

BufferedReader.close() 

cierra la corriente de según Javadoc para BufferedReader y InputStreamReader

así como

FileReader.close() 

hace.

+7

+1 para la combinación de nitidez y claridad. – CPerkins

+11

A menos que el constructor de 'BufferedReader' arroje una excepción. Es más limpio solo para cerrar la transmisión subyacente, aunque debes tener cuidado con los decoradores con otros recursos y el almacenamiento en búfer. –

+6

El Javadoc no dice si 'BufferedReader.close()' cierra el lector subyacente. Su descripción simplemente se copia de 'Reader.close()'. Este puede ser el comportamiento real en la práctica, pero no está documentado. –

6

De acuerdo con la fuente BufferedReader, en este caso bReader.close llama a fReader.close por lo que técnicamente no tiene que llamar al último.

4

El código fuente para BufferedReader muestra que el subyacente está cerrado cuando cierra el BufferedReader.

+0

Realmente quiero dar un visto bueno para vincular a algo concreto, pero esto solo se refiere a la implementación OpenJDK, y como los JavaDocs no están claros para 'Reader # close()', esto no proporciona evidencia concreta de que Oracle JDK , por ejemplo, se implementa de manera similar. – searchengine27

83

Como han señalado otros, solo debe cerrar el envoltorio externo.

BufferedReader reader = new BufferedReader(new FileReader(fileName)); 

Hay muy pocas posibilidades de que esto podría filtrarse un identificador de archivo si el constructor BufferedReader inició una excepción (por ejemplo OutOfMemoryError). Si su aplicación está en este estado, cuán cuidadoso debe ser su limpieza podría depender de cuán importante es que no prive al sistema operativo de los recursos que podría asignar a otros programas.

La interfaz Closeable se puede utilizar si un constructor envoltura es probable que falle en Java 5 o 6:

Reader reader = new FileReader(fileName); 
Closeable resource = reader; 
try { 
    BufferedReader buffered = new BufferedReader(reader); 
    resource = buffered; 
    // TODO: input 
} finally { 
    resource.close(); 
} 

Java 7 código debe utilizar la patrón try-con-recursos:

try (Reader reader = new FileReader(fileName); 
    BufferedReader buffered = new BufferedReader(reader)) { 
    // TODO: input 
} 
+3

Gracias, eso fue muy esclarecedor. – Zilk

+0

En la misma línea: http://stackoverflow.com/a/2732760/281545 –

0

Solo necesita cerrar el bufferReader ie reader.close() y funcionará bien.

3

Después de comprobar el código fuente, descubrí que para el ejemplo:

FileReader fReader = new FileReader(fileName); 
BufferedReader bReader = new BufferedReader(fReader); 

el método close() en BufferedReader objeto llamaría al método abstracto close() de lector de clase que en última instancia llamar al método implementado en InputStreamReader clase, que luego cierra el objeto InputStream.

Por lo tanto, solo bReader.close() es suficiente.

+1

Lo que muestra el código fuente no se puede citar como referencia. Es lo que dice la * especificación *, en este caso, el Javadoc, en el que se puede confiar. – EJP

Cuestiones relacionadas