2011-02-05 17 views
12

Al leer desde un archivo de texto, normalmente se crea un FileReader y luego se anida en un BufferedReader. ¿Cuál de los dos lectores debería cerrar cuando termine de leer? ¿Importa?Cerrar el lector anidado

FileReader fr = null; 
BufferedReader br = null; 
try 
{ 
    fr = new FileReader(fileName); 
    br = new BufferedReader(fr); 
    // ... 
} 
finally 
{ 
    // should I close fr or br here? 
} 

Soy un poco paranoico cuando se trata de excepción de seguridad. ¿Qué sucede cuando el constructor BufferedReader lanza una excepción? ¿Se cierra el lector anidado? ¿O se garantiza que no lanzará?

Respuesta

9

Generalmente, close() en la envoltura de flujo externo llamará a close() en las transmisiones envueltas. Sin embargo, si crees que es probable que un constructor arroje una excepción, haz un uso liberal de la interfaz Closeable.

FileReader fr = new FileReader(fileName); 
Closeable res = fr; 
try { 
    BufferedReader br = new BufferedReader(fr); 
    res = br; 
} finally { 
    res.close(); 
} 

Por lo tanto, incluso si la JVM se quedó sin espacio de almacenamiento dinámico para el búfer y arrojó un error, usted no se escapan un identificador de archivo.

Para Java 7 y superior try de uso-con-recursos:

try (FileReader fr = new FileReader(fileName); 
    BufferedReader br = new BufferedReader(fr)) { 
    // do work 
} 
+1

+1. Mucho más elegante que mi solución. –

+0

Buena solución si está trabajando con múltiples envoltorios que lanzan excepciones (y similares). Por supuesto, puede verificar la documentación y el código del 'BufferedReader' para ver si hay alguna posibilidad de una excepción en el ctor. – fwielstra

0

Cerrar solo el BufferedReader es suficiente, porque envuelve el FileReader. Si observa el source code de BufferedReader, verá que el método close cierra la transmisión envuelta.

+0

'buf = new char [8192];' Ew, número mágico! – fredoverflow

0

Cierre el BufferedReader en un bloque finally.

0

Si llama método de cierre del BufferedReader, el BufferedReader llamará método close del FileReader. Por lo tanto, se llaman ambos métodos cercanos. Más precisamente, el BufferedReader no hará nada PERO llamando al método de cierre del FileReader. Por lo tanto, no importa en absoluto. Aunque creo que también es una buena práctica, llame al método de cierre de BufferedReader.

0

No se garantiza nada para tirar. Debido a que el buffer está asignado, puede arrojar OutOfMemoryError. Usualmente separo mi código en 2 secciones: adquirir recursos y luego usar recursos. Cada sección tiene generalmente la limpieza única necesita

Este es el código para ilustrar:

// Acquire resources section. 

final FileReader fr = new FileReader(fileName); 

BufferedReader br = null; 

try 
{ 
    br = new BufferedReader(fr); 
} 
finally 
{ 
    if (br == null) 
    { 
     // Note that you are closing the fr here 
     fr.close(); 
    } 
} 

// Use resources section 
try 
{ 
    // ... use br 
} 
finally 
{ 
    // Now that br is safely constructed, just all its close 
    br.close(); 
} 

y estoy de acuerdo con usted, no hay nada digno de silencio sacó un identificador de archivos en el servidor de aplicaciones de larga ejecución.