2009-09-07 11 views
152

lese ich eine lokale Datei ein BufferedReader um einen Filereader eingewickelt mit:Muss ich FileReader und BufferedReader schließen()?

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

Habe ich die FileReader auch auf close() müssen, oder wird der Wrapper damit umgehen? Ich habe Code gesehen, wo die Menschen so etwas tun:

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

Diese Methode von einem Servlet aufgerufen wird, und ich möchte sicherstellen, ich lasse keine Griffe offen.

+4

Wissen Sie, Sie können einfach die Quelle für Informationen wie folgt lesen. Es ist alles in src.zip im JDK-Installationsverzeichnis, oder Sie können es online lesen zum Beispiel http://www.docjar.com/html/api/java/io/BufferedReader.java.html – gustafc

+36

Jemandem zu sagen, zu lesen Die Quelle ist schlimmer als "RTFM!" zu sagen. Und was ist, wenn die Quelle einen Bug hat? implizit wollen wir wissen, was das * richtige * Verhalten ist? – Raedwald

+1

Nun ... von diesem Gesichtspunkt aus: auf API-Spezifikationen zu zeigen ist dann nicht besser. Wenn die Quelle keinen Fehler hat, der dazu führt, dass sie sich nicht so verhält, wie in den Dokumenten angegeben, können Sie die Dokumente nicht verwenden. Es gibt also keinen guten Weg, eine solche Frage zu beantworten. – Atmocreations

Antwort

179

nein.

BufferedReader.close() 

schließt den Strom nach Javadoc- für BufferedReader und InputStreamReader

sowie

FileReader.close() 

tut.

+7

+1 für die Kombination von Prägnanz und Klarheit. – CPerkins

+11

Es sei denn, der Konstruktor für "BufferedReader" löst eine Ausnahme aus. Es ist sauberer, nur den zugrunde liegenden Stream zu schließen, obwohl Sie auf Dekoratoren mit anderen Ressourcen und Pufferung achten müssen. –

+6

Der Javadoc sagt nicht, ob 'BufferedReader.close()' den zugrunde liegenden Reader schließt. Seine Beschreibung wird einfach von 'Reader.close()' kopiert. Dies kann das tatsächliche Verhalten in der Praxis sein, aber es ist nicht dokumentiert. –

6

Laut BufferedReader-Quelle, in diesem Fall bReader.close, rufen Sie fReader.close auf, so dass Sie das letztere technisch nicht aufrufen müssen.

4

Der Quellcode für BufferedReader zeigt, dass der Basiswert geschlossen ist, wenn Sie den BufferedReader schließen.

+0

Ich möchte dies wirklich mit einem Daumen nach oben für die Verknüpfung mit etwas Konkretem, aber dies bezieht sich nur auf die OpenJDK-Implementierung, und da die JavaDocs sind unklar für 'Reader # close()', liefert dies keinen konkreten Beweis, dass das Oracle JDK wird zum Beispiel in ähnlicher Weise implementiert. – searchengine27

83

Wie andere darauf hingewiesen haben, müssen Sie nur die äußere Hülle schließen.

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

Es gibt eine sehr geringe Chance, dass dies eine Datei-Handle auslaufen könnte, wenn der BufferedReader Konstruktor eine Ausnahme ausgelöst hat (z OutOfMemoryError). Wenn sich Ihre App in diesem Zustand befindet, hängt es möglicherweise davon ab, wie wichtig es ist, dass Sie das Betriebssystem nicht Ressourcen berauben, die es anderen Programmen zuweisen könnte.

Die Closeable Schnittstelle kann, wenn ein in Java 5 oder 6-Wrapper-Konstruktor verwendet werden wahrscheinlich scheitern:

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

Java 7 Code die Try-mit-Ressourcen verwenden sollte Muster:

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

Danke, das war sehr aufschlussreich. – Zilk

+0

In die gleiche Richtung: http://stackoverflow.com/a/2732760/281545 –

0

Sie müssen nur den bufferedReader schließen, dh reader.close() und es wird gut funktionieren.

3

Nach der Quellcode überprüft, fand ich, dass für das Beispiel:

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

die Methode close() auf BufferedReader Objekt die abstrakte Methode close() von Reader Klasse nennen würde die würde schließlich Rufen Sie die implementierte Methode in InputStreamReader Klasse, die dann das InputStream Objekt schließt.

Also, nur bReader.close() ist ausreichend.

+1

Was der Quellcode zeigt, ist nicht als Referenz zitierbar. Es ist, was die * Spezifikation * sagt, in diesem Fall der Javadoc, auf den man sich verlassen kann. – EJP