2009-09-07 254 views
152

我讀使用周圍的FileReader包裹一個BufferedReader本地文件:我是否需要關閉()FileReader和BufferedReader?

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

我需要close()FileReader爲好,或將包裝處理這個問題? 我見過的代碼裏的人做這樣的事情:

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

這種方法是從servlet調用,我想確保我不會留下任何的把手打開。

+4

你知道,你可以閱讀這個信息的來源。它全部存放在JDK安裝目錄的src.zip中,或者您可以在線閱讀它,例如http://www.docjar.com/html/api/java/io/BufferedReader.java.html – gustafc 2009-09-07 10:46:02

+36

告訴某人閱讀該來源比說「RTFM!」更糟糕。如果源有錯誤怎麼辦?隱含地,我們想知道*正確*行爲是什麼? – Raedwald 2013-07-05 11:48:05

+1

那麼......從這個角度來看:指向API規範並不是那麼好。如果源文件沒有導致其不像文檔中指定的那樣發生錯誤,則不能依賴文檔。所以沒有辦法回答這樣的問題。 – Atmocreations 2015-09-18 07:40:18

回答

179

沒有。

BufferedReader.close() 

根據Javadoc中BufferedReaderInputStreamReader

以及

FileReader.close() 

確實關閉該流

+7

+1簡潔明瞭。 – CPerkins 2009-09-07 12:44:47

+11

除非'BufferedReader'的構造函數拋出異常。儘管你需要注意裝飾器與其他資源和緩衝,但關閉底層流更簡潔。 – 2009-09-07 14:55:44

+6

Javadoc沒有說「BufferedReader.close()」是否關閉了底層的閱讀器。它的描述只是從'Reader.close()'複製而來。這可能是實際中的實際行爲,但沒有記錄。 – 2015-03-30 22:12:18

6

根據BufferedReader來源,在這種情況下,bReader.close調用fReader.close,所以在技術上你不必調用後者。

4

BufferedReader的源代碼顯示關閉BufferedReader時底層已關閉。

+0

我真的很想給這個鏈接一個具體的東西,但這只是指OpenJDK的實現,並且由於JavaDocs不清楚'Reader#close()',這並沒有提供具體的證據證明Oracle JDK例如,以類似的方式實施。 – searchengine27 2015-10-29 22:15:48

83

正如其他人指出的,您只需關閉外包裝。

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

有一個非常渺茫的機會,這可能泄漏的文件句柄如果BufferedReader構造函數拋出異常(例如OutOfMemoryError)。如果你的應用程序處於這種狀態,那麼你的清理工作需要多小心可能取決於你不會剝奪操作系統可能想要分配給其他程序的資源的重要性。

Closeable接口可用於如果一個封裝構造是可能在Java 5或6到失敗:

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

Java 7的代碼應使用試穿與資源圖案:

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

謝謝,這非常有啓發性。 – Zilk 2009-09-07 11:08:56

+0

以同樣的方式:http://stackoverflow.com/a/2732760/281545 – 2014-04-15 15:41:02

0

你只需要關閉bufferedReader即reader.close(),它會正常工作。

3

檢查源代碼後,我發現對於例如:

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

的BufferedReader的close()方法對象將調用讀卡器類的抽象close()方法這將最終調用InputStreamReader類的實現方法,然後關閉InputStream對象。

所以,只有bReader.close()就足夠了。

+1

源代碼顯示的內容不適合作爲參考。這就是*規範*所說的,在這種情況下,可以依賴於Javadoc。 – EJP 2015-12-10 04:18:06