web-dev-qa-db-ja.com

ByteArrayInputStreamを閉じる必要がありますか?

短い質問、

私はByteArrayInputStreamが次のように作成されたいくつかの古いコードを見ました:

new BufferedReader(new InputStreamReader(new ByteArrayInputStream(somebytes)));

次に、BufferedReaderを使用してsomebytesを1行ずつ読み取ります。
すべて正常に動作していますが、BufferedReaderが閉じられていないことに気付きました。
これは長期実行のwebsphereアプリケーションですべて機能しており、somebytesはひどく大きくない(ほとんどが200k)、週に数回しか呼び出されず、明らかなメモリは発生していませんリーク。したがって、すべてのオブジェクトが正常にガベージコレクションされることを期待しています。

finallyステートメントで、入出力ストリームを閉じる必要があることを常に(一度だけ)学びました。 ByteStreamsはこのルールの例外ですか?

親切にジェローエン。

42
dr jerry

ByteArrayInputStreamを閉じる必要はありません。変数から参照されなくなった時点で、ガベージコレクターはストリームとsomebytesを解放します(もちろん、他の場所で参照されていないと想定します)。

ただし実際には、すべてのストリームを閉じることをお勧めします。実際、ストリームを作成する実装は、生のバイトではなく将来変更される可能性があります。ファイルを読みますか?また、PMDや FindBugs (コメントを参照)おそらく文句を言うでしょう。

ストリームを閉じて不可能なIOExceptionを処理せざるを得なくなった場合は、 IOUtils を使用できます。

IOUtils.closeQuietly(stream);
44

読者を閉じることは常に良い習慣です。ただし、ByteArrayInputStreamを閉じなくても、ファイルにアクセスしていないため、メモリ内のバイト配列のみであるため、潜在的な悪影響はありません。

7
jzd

@TomaszNurkiewiczが述べたように、開いているストリームを閉じることは常に良いことです。 tryブロック自体を実行させる別の良い方法。次のようなリソースで試してください...

try ( InputStream inputStream = new ByteArrayInputStream(bytes); Workbook workBook = new XSSFWorkbook(inputStream)) { 

ここでWorkbookとInputStreamはどちらもCloseable Interfaceを実装しているため、tryブロックが完了すると(通常または突然)、ストリームは確実に閉じられます。

2
KulDeep

リソースはfinally(または同等のもの)で閉じる必要があります。ただし、バイト数がある場合は問題ありません。書くときは、幸せな場合はflushに注意してください。