BufferedOutputStream不会抛出I / O异常

时间:2017-03-29 05:35:44

标签: java file-io fileoutputstream bufferedinputstream

在处理C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin>gradle wrapper Starting a Gradle Daemon (subsequent builds will be faster) :wrapper FAILED FAILURE: Build failed with an exception. * What went wrong: Some problems were found with the configuration of task ':wrapper'. > Cannot write to file 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle\wrapper\gradle-wrapper.properties' specified for property 'propertiesFile', as ancestor 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle' is not a directory. > Cannot write to file 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle\wrapper\gradle-wrapper.jar' specified for property 'jarFile', as ancestor 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle' is not a directory. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. 时发现,当我们在关闭流后写入时,它不会抛出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();
        }
    }
}

有人可以帮助我,为什么这种行为有所不同?

3 个答案:

答案 0 :(得分:5)

  

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

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

FileOutputStream抛出os.write(...)上的异常而不是BufferedOutputStream的原因是它立即将IO写入底层本机层。如果您在os.flush()之后向BufferedOutputStream添加os.write()调用,那么您将看到相同的异常,因为这会强制写出其内部缓冲区。

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的{​​{1}}方法(实际上在close()基类中)时,您可以看到输出流未设置为FilterOutputStream或任何东西:

null

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

现在将该代码与close()

进行比较
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()设置为Writer。更好的IMO。

答案 1 :(得分:0)

因为BufferedOutputStream将字节写入内部字节缓冲区,所以在调用时会写入底层输出流,因此如果在{{1}之后调用flush它将抛出异常,但是在这里你尝试在文件流关闭后直接写入文件流,因此例外,这里不足为奇

答案 2 :(得分:0)

在检查JDK代码后发现ensureOpen()方法抛出IOException并且详细消息为"流已关闭"在BufferedOutputStream中丢失。根据我的理解,这必须在那里。