ネストされた読者を閉じます
-
29-10-2019 - |
質問
テキストファイルから読むとき、通常は FileReader
そして、aに巣を作ります 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
コンストラクターは例外をスローしますか?ネストされた読者を閉じますか?それとも、投げることが保証されていますか?
解決
一般的、 close()
最も外側のストリームでラッパーが呼び出します close()
ラップストリームで。ただし、コンストラクターが例外を投げる可能性が高いと思われる場合は、 閉鎖可能 インターフェース。
FileReader fr = new FileReader(fileName);
Closeable res = fr;
try {
BufferedReader br = new BufferedReader(fr);
res = br;
} finally {
res.close();
}
したがって、JVMがバッファ用のヒープスペースを使い果たしてエラーを投げたとしても、ファイルハンドルを漏らしません。
Java 7以降の場合は、リソースを使用してください:
try (FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr)) {
// do work
}
他のヒント
閉じます BufferedReader
それがラップしているので、十分です FileReader
. 。あなたが見たら ソースコード の BufferedReader
あなたはそれを見るでしょう close
方法、ラップストリームを閉じます。
最終的なブロックでバッファレッドリーダーを閉じます。
BufferedReaderの緊密な方法を呼び出すと、BufferedReaderはFileReaderの緊密な方法を呼び出します。したがって、両方の閉鎖方法が呼び出されます。より正確には、BufferedReaderは何もしません しかし Filreaderの密接な方法を呼び出します。したがって、それはまったく問題ではありません。良い練習だと思いますが、BufferedReaderの緊密な方法を呼び出します。
投げないように保証されているものはありません。バッファが割り当てられているため、OffMemoryErrorを捨てる可能性があります。通常、コードを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( );
}
そして、私はあなたに同意します、長いランニングサーバーアプリケーションのファイルハンドラーを静かに緩めるほどの価値はありません。