2013-01-21 77 views
29

は、このコードApache commons-io IOUtils.close Quietlyを使用しても安全ですか?

BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt")); 
    try { 
     bw.write("test"); 
    } finally { 
     IOUtils.closeQuietly(bw); 
    } 

安全かいませんか?私がBufferedWriterを閉じたときに理解している限り、そのバッファを基になるストリームにフラッシュし、エラーのために失敗する可能性があります。しかし、IOUtils.closeQuietly APIは、例外は無視されると言います。

IOUtils.close Quietlyのためにデータが失われる可能性はありますか?

+5

答えはありませんが、[try-with-resources](http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)ステートメントは、IOUtils.closeQuietlyを使用するためのほとんどのニーズを排除します。 。 – lyomi

+1

良い答えですが、この機能はJava 7で新しく追加されました。何らかの理由でJava 6を使用している場合(古いAndroidバージョンなど)、 'closeQuietly()'はまだまだです。 –

答えて

34

コードがcloseQuietly()のJavadocをについて次のようになります。

BufferedWriter bw = null; 

try { 
    bw = new BufferedWriter(new FileWriter("test.txt")); 
    bw.write("test"); 
    bw.flush(); // you can omit this if you don't care about errors while flushing 
    bw.close(); // you can omit this if you don't care about errors while closing 
} catch (IOException e) { 
    // error handling (e.g. on flushing) 
} finally { 
    IOUtils.closeQuietly(bw); 
} 

closeQuietly()は、一般的な使用の代わりに、開閉可能に直接close()を呼び出すためのものではありません。その目的は、最終ブロック内のクローズを確実にすることです。すべてのエラー処理は、その前に実行する必要があります。

つまり、close()またはflush()のコール中に例外に反応する場合は、通常の方法で処理する必要があります。最終ブロックにcloseQuietly()を追加すると、閉じることができます。フラッシュが失敗し、closeがtry-blockで呼び出されなかったとき。

+0

私はbw.flush()が不要だと思いますが、bw.close()はflush()を呼び出します。 –

+2

@EvgeniyDorofeevあなたはそこに 'close()'を残している限りです。しかし、フラッシュ中に例外が気になるだけで、近くになければ、ここで明示的にフラッシュする必要があります。例を少し普遍的にするために、両方のメソッド呼び出しを書いただけです。 –

+0

ちょうど明白であるべきです:あなたは 'bw.close()'への呼び出しを省略でき、bwはfinally {}節で正しく閉じられます。このようにすることで、 'bw.close()'の間のエラーを知ることができます。 –

5

理論的には可能ですが、close()が失敗したことを今まで見たことはありません。通常は失敗すると、ファイルを開くなどの以前のIO操作が最初に失敗することを意味します。 IOExceptionを無視しないクローズを書くことができますが、失敗したtry/catchブロックの中に例外の真の原因が壊れる可能性があります。何をしたい

は、それはあまりにも長い間、アプリケーションが書き込みがエラーなしで成功したかどうかを気にしないように安全である(ほとんどの場合、やり過ぎである)以下の

try { 
    // write to bw. 
    bw.close(); // throw IOException if an error occurs. 

} finally { 
    // don't clobber a previous IOException 
    IOUtils.closeQuietly(bw); 
} 
+2

あなたはそれを間違って使用しています - 'IOUtils.closeQuietly()'は、Closableでclose()を直接呼び出すのではなく、一般的な使用のためのものではありません。その目的は、リソースリークを避けるためにfinallyブロック内でclose()が呼び出されるようにすることです。前にすべてのエラー処理(ロギング、例外のラッピングおよび再スロー化)を行う必要があります - Fabianの答えを参照してください。 –

+0

@JarekPrzygódzki最後にあなたは特に近くにIOExceptionを見た? –

+0

これはまれですが、それは起こります。クローズ可能なストリームや{Input、Output}ストリームの背後にあるものは決してわかりません。そして、例外を抑止することは、決してうまくいかない。 –

7

のようなものです。アプリケーションで書き込みエラーを処理する必要がある場合は、buffered data flushed on closeが失われてエラーが発生する可能性があります。

関連する問題