Java BufferedOutputStream未引发I/O异常

Java BufferedOutputStream未引发I/O异常,java,file-io,fileoutputstream,bufferedinputstream,Java,File Io,Fileoutputstream,Bufferedinputstream,在处理BufferedOutputStream时,我们在关闭流后对其进行写入时,发现它不会抛出IOException 为了验证我的结果,我检查了FileOutputStream发现它在关闭后尝试写入时抛出了IOException public class Test { public static void main(String[] args) { try { // Created a byte[] barry1 barry2

在处理
BufferedOutputStream
时,我们在关闭流后对其进行写入时,发现它不会抛出
IOException

为了验证我的结果,我检查了
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();
        }
    }
}

有人能帮我吗,为什么这种行为不同

因为
bufferedoutput流
将字节写入其内部字节缓冲区,然后调用时写入底层输出流,因此如果在
os.write(c)之后调用flush,它将抛出异常,但在这里,您尝试在文件流关闭后直接写入文件流,因此出现异常,这并不奇怪

在处理BufferedOutputStream时,我们在关闭流后对其进行写入时发现它不会引发IOException

BufferedOutputStream
代码没有这种检查功能,但是
FileOutputStream
也没有。在这两种情况下,只有当IO实际写入磁盘时,操作系统才会“抛出”IOException。检测到流已关闭的不是Java代码。另一方面,这可能意味着一些本机实现根本不会抛出

缓冲输出流
相比,
文件输出流
操作系统上引发异常。write(…)
,原因是它正在将IO立即写入底层本机层。如果在
os.write()
之后添加对
BufferedOutputStream
os.flush()
调用,则会看到相同的异常,因为这会强制写出其内部缓冲区

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
查看
BufferedOutputStream
close()
方法(实际上是在
FilterOutputStream
基类中),可以看到输出流未设置为
null
或任何内容:

public void close() throws IOException {
    try {
      flush();
    } catch (IOException ignored) {
    }
    out.close();
}
我也不喜欢它忽略关闭时的IOExceptions。哇!这告诉我,我们应该在
close()
之前手动调用
flush()
,这是我特别不做的模式

现在将该代码与BufferedWriter.close()进行比较:


BufferedWriter.close()
不接受异常,并将委托的
Writer
设置为
null
。更好。

检查JDK代码后发现,BufferedOutputStream中缺少引发IOException并带有详细消息“Stream closed”的方法。从我的理解来看,这一定存在。

不,我认为当
缓冲输出流
关闭时(而不是
文件输出流
)写入该流不会引发异常,这仍然令人惊讶。我可以理解OP是否正在关闭下面的
FileOutputStream
,但我希望
BufferedOutputStream
也能检查一下。请@JonSkeet发表一条评论…:)先生,请勾选+1。在我尝试调用outputsteam.flush()之前,我也有同样的疑问。当outputstream关闭时,该调用立即引发IOException。
public void close() throws IOException {
    synchronized (lock) {
        if (out == null) {
            return;
        }
        try {
            flushBuffer();
        } finally {
            out.close();
            out = null;   // good doggie
            cb = null;
        }
    }
}