2013-01-23 7 views
20

このコードはjava.io.BufferedOutputStreamは安全に使用できますか?一見

BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("1.txt")); 
byte[] bytes = new byte[4096]; 
bout.write(bytes); 
bout.close(); 

完全にOKと思われるが、我々は詳しく見ていくならば、我々は

public void close() throws IOException { 
    try { 
     flush(); 
    } catch (IOException ignored) { 
    } 
    out.close(); 
} 

それが原因にflush()エラーは無視されることは可能ですが、以下のようclose()が実装されていることがわかりますデータが失われ、プログラムがそれに気付かないことがありますか? FilterOutputStream.closeBufferedOutputStreamclose()を継承しています)APIには何の危険も言及されていません。

UPDATE:私は、フラッシュメモリへの書き込みテストを変えbout.close前に、5秒のスリープを追加しました)(クローズ時のIOエラーをシミュレートするため()とテストが寝ている間に私はUSBからフラッシュを取り除きます。テストは例外なく終了しましたが、Flashを挿入してチェックしたときに、1.txtはそこにはありませんでした。

その後、私は

BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("g:/1.txt")) { 
     @Override 
     public void close() throws IOException { 
      flush(); 
      super.close(); 
     } 
    }; 

)(クローズオーバーライドして、再度テストを実行し、それがあるので、私はcloseを呼び出すと、実際には、データを失わせることができることを理由でしょう

Exception in thread "main" java.io.FileNotFoundException: g:\1.txt (The system cannot the specified path) 
    at java.io.FileOutputStream.open(Native Method) 
    at java.io.FileOutputStream.<init>(FileOutputStream.java:212) 
    at java.io.FileOutputStream.<init>(FileOutputStream.java:104) 
    at test.Test1.main(Test1.java:10) 
+0

'FilterOutputStream' typo? –

+3

openjdk 'close()'メソッドのバグとして表示されます。 - デッドストアを無視する... –

+0

@Nikolayいいえ、そうではありません。 BufferedOuptutStreamはそこから近く継承し、言及するのを忘れた –

答えて

5

を持って、それ以来、潜在的なIOExceptionは黙って無視されています(誰がそのことを開発者の心に通したのかを知っています...)。それはプログラマの側に力を入れないものの

まともな代替手段は、特にtry/finallyブロックで、@Tomによるコメントで述べたように、(正確性IOExceptionを扱う)close前に、明示的にflushを呼び出すことです。

この問題は、AutoCloseableオブジェクトのためにJava7でさらに悪化する可能性があります。これは、close()メソッドを明示的に呼び出さないためで、この種の回避策はより簡単にスリップすることができます。

+0

おそらくflush()から例外を処理する方法がわからないので、例外が抑制されていない可能性があります。 – irreputable

+1

私は、Exceptionをスローし、何かが間違っていることを明示的にユーザに知らせるのは依然として安全だと思います。 – pcalcao

関連する問題