次の解決策は、クローズの前に可能な例外を非表示にすることなく、クローズが失敗した場合に正しく例外をスローします。
try {
InputStream in = new FileInputStream(file);
try {
// work
in.close();
} finally {
Closeables.closeQuietly(in);
}
} catch(IOException exc) {
// kernel panic
}
これは、close を 2 回呼び出しても効果がないため機能します。
これはguava Closeablesに依存していますが、squiddle で示されているように、必要に応じて独自の closeQuietly メソッドを作成できます( serg10も参照)。
一般的なケースでは、クローズ エラーを報告することは重要です。なぜなら、クローズは、たとえばバッファリングのために、いくつかの最終バイトをストリームに書き込む可能性があるためです。したがって、ユーザーは失敗したかどうかを知りたいか、何らかの方法で行動したいと考えています。確かに、これは FileInputStream の特定のケースでは当てはまらないかもしれませんが、私にはわかりません (ただし、既に述べた理由から、とにかく発生した場合はクローズ エラーを報告する方がよいと思います)。
上記のコードは、try ブロックが埋め込まれているため、少しわかりにくいです。IOException をスローするメソッドと、IOException をキャッチするメソッドの 2 つのメソッドを使用すると、より明確になると考えられます。少なくともそれが私が選ぶものです。
private void work() throws IOException {
InputStream in = new FileInputStream(file);
try {
// work
in.close();
} finally {
Closeables.closeQuietly(in);
}
}
public void workAndDealWithException() {
try {
work();
} catch(IOException exc) {
// kernel panic
}
}
http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.htmlに基づく(McDowell が参照)。