2017-03-29 2 views
3

BufferedOutputStreamで作業している間に、ストリームを閉じた後に書き込んだときにIOExceptionをスローしません。BufferedOutputStreamがI/O例外をスローしない

私の結果を確認するには、FileOutputStreamが、それを閉じた後でそれに書き込もうとしたら、IOExceptionを投げていることがわかりました。

public class Test { 
    public static void main(String[] args) { 
     try { 
      // Created a byte[] barry1 barry2 
      byte[] barry1 = { '1', '3' }; 
      byte[] barray2 = { '2', '4' }; 
      OutputStream os = new BufferedOutputStream(
        new FileOutputStream("abc.txt", false)); 
      // Writing to stream 
      os.write(barry1); 
      os.close(); 
      os.write(barray2); // this suceeds - bug 

      os = new FileOutputStream("abc.txt", true); 
      //Writing to stream 
      os.write(barry1); 
      os.close(); 
      os.write(barray2); // crashes here, correct. 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

なぜこの動作が異なるのですか? os.write(c);後のコールフラッシュ、それは例外がスローされますので、もし

答えて

4

BufferedOutputStreamでの作業中に、ストリームを閉じた後にIOExceptionをスローしませんでした。

BufferedOutputStreamコードは、ちょうどチェックの並べ替えを持っていません - しかし、その後どちらもFileOutputStreamを行います。どちらの場合も、IOが実際にディスクに書き込まれるときに限り、OSはIOExceptionを「スロー」します。ストリームが閉じられたことを検出しているのはJavaコードではありません。これはおそらく、一部のネイティブ実装がまったく投げていないことを意味します。

に対してos.write(...)と例外を投げているのは、BufferedOutputStreamと比べて、IOをすぐに元のネイティブレイヤーに書き込んでいるためです。 os.write()の後にos.flush()コールをBufferedOutputStreamに追加すると、その内部バッファが強制的に書き出されるため、同じ例外が表示されます。

OutputStream os = new BufferedOutputStream(new FileOutputStream("abc.txt", false)); 
os.write(barry1); 
os.close(); 
os.write(barray2); // this suceeds – unfortunate behavior 
os.flush(); // adding this line throws an IOException 

(実際FilterOutputStream基底クラスで)BufferedOutputStreamclose()方法を見ると、あなたが出力ストリームはnullか何かに設定されていないことがわかります。

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

また、私はドンここに近いところでIOExceptionsを無視しているような気がする。ワオ。これは、私が具体的にしないパターンであるclose()の前に常にflush()と呼ぶべきであることを私に伝えます。

は今BufferedWriter.close()にそのコードを比較する:

public void close() throws IOException { 
    synchronized (lock) { 
     if (out == null) { 
      return; 
     } 
     try { 
      flushBuffer(); 
     } finally { 
      out.close(); 
      out = null; // good doggie 
      cb = null; 
     } 
    } 
} 

BufferedWriter.close()は例外を食べて、nullことに委任Writerを設定しません。はるかに良いIMO。

0

呼び出されたときBufferedOutputStreamは、その後、その内部のバイトのバッファをバイトを書き込むためには、基本となる出力に含まストリームに書き込みますが、ここであなたはへの書き込みをしてみてくださいファイルストリームが閉じられた直後であるため、例外はありません。ここでは驚きはありません。

+1

いいえ、私は、 'FileOutputStream'ではなく*が*閉じているときに' BufferedOutputStream'に書き込むと例外がスローされないことはまだ驚きです。OPが 'FileOutputStream'を閉じているのかどうかは分かりましたが、' BufferedOutputStream'にもチェックがあると思います。 –

+1

@JonSkeetから好意的なコメントをいただきました。:) –

0

JDKコードを確認した後、ensureOpen()メソッドが、BufferedOutputStreamに「Stream closed」の詳細メッセージを含むIOExceptionをスローするメソッドが見つからないことを確認しました。私の理解から、これはそこになければならない。

関連する問題