2012-01-20 17 views
5

私はInputStreamからバイトを読み込み、すべてのバイトの読み込みが終了している(またはストリームの最後まで読み込むつもりはない)ので、close()にストリームに関連付けられたシステムリソースを解放する必要があることを理解しています。ストリームはエラーで自動的に閉じられますか?

readバイトがあり、それがjava.io.IOExceptionをスローしたのですが、まだclose()と呼んでストリームに関連付けられたシステムリソースを解放する必要がありますか?

エラー時にストリームが自動的に閉じられるので、close()に電話する必要はありません。

+0

GCed時にリソースは閉じられます。だから、まれに例外処理がスローされる問題があります。確定的なリソース管理のためには、常にclose()を呼び出す必要があります。 –

+0

@PeterLawreyあなたは、GCが 'close()'によってスローされたIOExceptionをGCが静かに食べるので、私たちは 'close()'を呼び出すべきだと言っていますか?したがって、close()のインタフェースがExceptionの形式をスローしない場合、ストリームにエラーが発生したときにclose()を呼び出す必要はありませんか? – Pacerier

+0

これは考慮すべき点ですが、close()によってスローされた例外を無視するのはかなり一般的な方法です。 GCを実行する際の問題は、これらのリソースをクリーンアップするGCをトリガーする前にファイルハンドルを実行できることです。あなたのプログラムは動作しているように見えるかもしれませんが、時折失敗することは避けたいものです。 –

答えて

6

OSそのものプロセス(つまりJVM)が終了するためストリームを閉じてリソースを解放しますが、強制する必要はありません。

このような場合には、ブロックを閉じる場所には常にfinallyブロックを実装する必要があります。このように:それは最初の場所で投げた場合

InputStream is = null; 

try { 
    is = new FileInputStream(new File("lolwtf")); 
    //read stuff here 
} catch (IOException e) { 
    System.out.println("omfg, it didn't work"); 
} finally { 
    is.close(); 
} 

これは実際に動作することが保証されていませんが、あなたのデータソースは、おそらく何らかの方法でめちゃめちゃにされているので、おそらくたいが、とにかくその時点で終了します。もし私がFileのオブジェクトを参考にしていたら、Fileのインターフェースを介してそれが存在するかどうかをチェックすることができますが、具体的なことは、InputStreamのプロバイダを守っているともっと詳しく知ることができます。あなたの特定のデータプロバイダに

この方法は、たとえば、Hibernateをスローするネットワークセッションでより便利になります。

+0

最後の段落はどういう意味ですか?あなたは*「finallyブロックを実装する」*の戦術を意味しますか? – Pacerier

+0

@Pacerier最終的にブロックにHibernateセッションを閉じるなど、かなり一般的であることを意味します。 – TC1

関連する問題