2011-02-05 122 views
12

從文本文件中讀取數據時,通常會創建一個FileReader,然後嵌套在BufferedReader中。讀完後我應該關閉哪兩位讀者?有關係嗎?關閉嵌套閱讀器

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

對於異常安全,我有點偏執。 BufferedReader構造函數拋出異常時會發生什麼?它是否關閉嵌套的閱讀器?還是保證不扔?

回答

9

通常,最外層流包裝器上的close()將在包裝流上調用close()。但是,如果您認爲構造函數可能會拋出異常,則可以自由使用Closeable接口。

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

因此,即使JVM耗盡了緩衝區的堆空間並拋出錯誤,也不會泄漏文件句柄。

對於Java 7及以上使用try-與資源:

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

+1。比我的解決方案更優雅。 – 2011-02-05 21:03:08

0

僅合計BufferedReader就足夠了,因爲它包裝了FileReader。如果您查看BufferedReadersource code,您將看到close方法將關閉包裝的流。

+0

`buf = new char [8192];`Ew,幻數! – fredoverflow 2011-02-05 19:54:21

0

在finally塊中關閉BufferedReader。

0

如果調用BufferedReader中的close方法,在BufferedReader類將調用的FileReader的close方法。因此這兩個關閉方法都被調用。更確切地說,BufferedReader什麼也不做但是調用FileReader的close方法。因此它根本不重要。雖然我認爲這也是一個很好的做法,也可以調用BufferedReader的close方法。

0

沒有保證不扔。由於分配了緩衝區,它可能會拋出OutOfMemoryError。我通常將我的代碼分成兩部分:獲取資源,然後使用資源。每個部分通常具有獨特的清理需要

下面是代碼來說明:

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

而且我同意你的觀點,沒有什麼價值超過默默地鬆在長時間運行的服務器應用程序的文件處理程序。