2011-02-05 3 views
12

テキストファイルから読み込む場合、通常はFileReaderが作成され、次にBufferedReaderにネストされます。私は読書を終えたときに2人の読者のうちどちらを閉じなければならないのですか?それは問題ですか?ネストされたリーダーを閉じる

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は、バッファ用のヒープ領域を使い果たし、エラーを投げた場合でも、あなたはファイルハンドルをリークしないでしょう。

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

+1。私のソリューションよりもはるかにエレガントです。 –

+0

例外をスローする可能性のある複数のラッパー(およびそれに類するもの)を扱っている場合は、良い解決策です。もちろん、 'BufferedReader'のドキュメントとコードをチェックして、実際に例外が発生する可能性があるかどうかを確認することができます。 – fwielstra

0

BufferedReaderのみを閉じると、FileReaderがラップされます。 がBufferedReaderの場合、closeメソッドがラップされたストリームを閉じます。

+0

buf = new char [8192]; 'Ew、マジックナンバー! – fredoverflow

0

finallyブロックでBufferedReaderを閉じます。

0

あなたはBufferedReaderののcloseメソッドを呼び出した場合は、BufferedReaderのは、FileReaderののcloseメソッドを呼び出します:トライで-リソースのJava 7の場合と使用上の

。したがって、両方のcloseメソッドが呼び出されます。より正確には、BufferedReaderは何もしません。BUTはFileReaderのcloseメソッドを呼び出します。したがって、全く問題ではありません。私はそれがBufferedReaderのcloseメソッドを呼び出すことも良い習慣だと思っています。

0

投げないことは何も保証されていません。バッファが割り当てられているため、OutOfMemoryErrorがスローされる可能性があります。私は通常、自分のコードを2つのセクションに分けます:リソースを獲得し、リソースを使用します。各セクションは、通常、独自のクリーンアップがここ

を必要としている説明するためのコードです:

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

そして、私はあなたに同意し、静かに長い実行中のサーバーアプリケーションでファイルハンドラを失うよりも価値があるものはありません。

関連する問題