2011-02-05 17 views
12

Durante la lettura da un file di testo, in genere viene creato uno FileReader e quindi nidifica in uno BufferedReader. Quale dei due lettori dovrei chiudere quando ho finito di leggere? Importa?Lettore nidificato di chiusura

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

Sono un po 'paranoico quando si parla di protezione dalle eccezioni. Cosa succede quando il costruttore BufferedReader genera un'eccezione? Chiude il lettore annidato? O è garantito non gettare?

risposta

9

Generalmente, close() sul wrapper di flusso più esterno chiamerà close() sui flussi avvolti. Tuttavia, se ritieni che sia probabile che un costruttore generi un'eccezione, fai un uso liberale dell'interfaccia Closeable.

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

Quindi, anche se la JVM ha esaurito lo spazio di heap per il buffer e ha gettato un errore, si dovrebbe non perdere un handle di file.

Per Java 7 e soprattutto l'uso prova-con-risorse:

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

+1. Molto più elegante della mia soluzione. –

+0

Buona soluzione se stai lavorando con più wrapper di lancio (e simili). Naturalmente, è possibile controllare la documentazione e il codice di 'BufferedReader' per vedere se c'è effettivamente qualche possibilità di eccezione nel ctor. – fwielstra

0

La chiusura solo di BufferedReader è sufficiente, poiché avvolge lo FileReader. Se si guarda il source code di BufferedReader vedrete che il metodo close, chiude il flusso avvolto.

+0

'buf = new char [8192];' Ew, numero magico! – fredoverflow

0

Chiudere BufferedReader in un blocco finale.

0

Se si chiama il metodo close del BufferedReader, il BufferedReader chiamerà metodo close del FileReader. Quindi vengono chiamati entrambi i metodi vicini. Più precisamente, BufferedReader non farà nulla MA chiamando il metodo close di FileReader. Quindi non importa affatto. Anche se penso che sia una buona pratica, chiama il metodo close del BufferedReader.

0

Nulla è garantito per non gettare. Poiché il buffer è allocato può lanciare OutOfMemoryError. Di solito separo il mio codice in 2 sezioni: acquisisco risorse e quindi utilizzo risorse. Ogni sezione ha di solito la pulizia unica ha bisogno

Ecco il codice per illustrare:

// 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(); 
} 

e sono d'accordo con te, non c'è niente vale la pena di perdere in silenzio un gestore di file nell'applicazione server di lunga esecuzione.