Czytam plik lokalny za pomocą BufferedReader owiniętego wokół FileReader:
BufferedReader reader = new BufferedReader(new FileReader(fileName));
// read the file
// (error handling snipped)
reader.close();
Czy muszę , jak również, czy będzie uchwyt wrapper że? Widziałem kod, w którym ludzie robią coś takiego:close()
FileReader
FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
// read the file
// (error handling snipped)
bReader.close();
fReader.close();
Ta metoda jest wywoływana z serwletu i chciałbym się upewnić, że nie zostawię otwartych uchwytów.
java
io
bufferedreader
filereader
Zilk
źródło
źródło
Odpowiedzi:
Nie.
zamyka strumień zgodnie z javadoc dla BufferedReader i InputStreamReader
jak również
robi.
źródło
BufferedReader
zgłosi wyjątek. Czystsze jest tylko zamknięcie podstawowego strumienia, chociaż musisz uważać na dekoratorów z innymi zasobami i buforowaniem.BufferedReader.close()
zamyka podstawowy czytnik. Jego opis jest po prostu skopiowany zReader.close()
. To może być rzeczywiste zachowanie w praktyce, ale nie jest to udokumentowane.Reader#close()
javadoc nie mówi, czy zamyka, czy jest owinięty Czytnik, czy nie. Wszystko,Closes the stream and releases any system resources associated with it.
co jest z tym związane, to to, że nie jest wystarczająco wyraźne, aby powiedzieć, że zamyka lub nie zamyka zasobu. „Zwolnij zasób” równie dobrze może usuwać wszelkie odwołania do zasobu w BufferedReader ... co oznaczałoby, że zasób nie jest zamknięty.Jak zauważyli inni, wystarczy zamknąć zewnętrzne opakowanie.
Istnieje bardzo niewielka szansa, że może to spowodować wyciek uchwytu pliku, jeśli
BufferedReader
konstruktor zgłosi wyjątek (npOutOfMemoryError
.). Jeśli aplikacja jest w tym stanie, to, jak ostrożne musi być czyszczenie, może zależeć od tego, jak ważne jest, aby nie pozbawiać systemu operacyjnego zasobów, które może chcieć przydzielić innym programom.Zamykane interfejs może być stosowane, jeżeli konstruktor wrapper może zawieść w Java 5 lub 6:
Kod Java 7 powinien używać wzorca try-with-resources :
źródło
Według źródła BufferedReader, w tym przypadku bReader.close wywołuje fReader.close, więc technicznie nie trzeba wywoływać tego ostatniego.
źródło
Kod źródłowy dla BufferedReader pokazuje, że instrument bazowy jest zamknięty po zamknięciu BufferedReader.
źródło
Reader#close()
, nie zapewnia to konkretnych dowodów na to, że Oracle JDK, na przykład, jest implementowany w podobna moda.Po sprawdzeniu kodu źródłowego znalazłem to na przykład:
metoda close () na obiekcie BufferedReader wywołałaby abstrakcyjną metodę close () klasy Reader, która ostatecznie wywołałaby zaimplementowaną metodę w klasie InputStreamReader , która następnie zamyka obiekt InputStream .
Tak więc wystarczy tylko bReader.close ().
źródło
Począwszy od wersji Java 7 można użyć instrukcji try-with-resources
Ponieważ
BufferedReader
instancja jest zadeklarowana w instrukcji try-with-resource, zostanie zamknięta niezależnie od tego, czy instrukcja try zakończy się normalnie czy nagle. Więc nie musisz go sam zamykać wfinally
wyciągu. (Dotyczy to również zagnieżdżonych instrukcji zasobów)Jest to zalecany sposób pracy z zasobami, więcej informacji można znaleźć w dokumentacji
źródło
Musisz tylko zamknąć bufferedReader tj. Reader.close () i będzie działał dobrze.
źródło
Jestem spóźniony, ale:
BufferReader.java:
źródło
Ty Nie trzeba zamknąć owinięte odczytującego / zapisującego.
Jeśli spojrzałeś na dokumenty (
Reader.close()
,Writer.close()
), zobaczysz, że wReader.close()
nim jest napisane:Co tylko mówi, że „uwalnia wszelkie związane z tym zasoby systemowe ”. Mimo że nie potwierdza ... daje ci ochotę zacząć szukać głębiej. a jeśli pójdziesz do
Writer.close()
niego to tylko stwierdza, że się zamyka.W takich przypadkach odsyłamy do OpenJDK, aby spojrzeć na kod źródłowy.
W BufferedWriter Line 265 zobaczysz
out.close()
. Więc to się nie zamyka ... To coś innego. Jeśli przeszukasz klasę pod kątem występowania „out
”, zauważysz, że w konstruktorze w linii 87, któraout
jest pisarzem, klasa zawija się tam, gdzie wywołuje innego konstruktora, a następnie przypisujeout
parametr do własnejout
zmiennej.Więc .. Co z innymi? Podobny kod można zobaczyć w BufferedReader Line 514 , BufferedInputStream Line 468 i InputStreamReader Line 199 . Inni nie znam, ale to powinno wystarczyć, by założyć, że tak.
źródło