`

IO 包装流关闭

    博客分类:
  • java
 
阅读更多
援引了一位网友的解释, 自己稍加改动, 保存留用

(1)JAVA的IO流使用了装饰模式,关闭最外面的流的时候会自动调用被包装的流的close()方吗?

(2)如果按顺序关闭流,是从内层流到外层流关闭还是从外层到内存关闭?



问题(1)解释:

如下例子代码:
  FileInputStream is = new FileInputStream(".");   
  BufferedInputStream bis = new BufferedInputStream(is);  
  bis.close();


从设计模式上看:
java.io.BufferedInputStream是java.io.InputStream的装饰类。
BufferedInputStream装饰一个 InputStream 使之具有缓冲功能,is要关闭只需要调用最终被装饰出的对象的 close()方法即可,因为它最终会调用真正数据源对象的 close()方法。

BufferedInputStream的close方法中对InputStream进行了关闭,下面是jdk中附带的源代码:
java.io.BufferedInputStream的api:
close
public void close()throws IOException 关闭此输入流并释放与该流关联的所有系统资源。
复制代码
因此,可以只调用外层流的close方法关闭其装饰的内层流,验证例子:

  public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("d:\\a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write("java IO close test");
         
        bw.close();
      
     }



验证ok


问题(2)解释:如果不想使用(1)方式关闭流,可以逐个关闭流(可能大家比较习惯吧)

如下例子:
public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("d:\\a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write("java IO close test");
       
        //从内带外顺序顺序会报异常
        fos.close();
        osw.close();
        bw.close();

     }


报出异常:
Exception in thread "main" java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:26)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:99)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
at java.io.BufferedWriter.close(BufferedWriter.java:246)
at com.my.test.QQ.main(QQ.java:22)


如下例子:
 public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("d:\\a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write("java IO close test");

        // 从外到内顺序关闭ok
        bw.close();
        osw.close();
        fos.close();
    }



验证ok
一般情况下是:先打开的后关闭,后打开的先关闭

另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b

例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b

当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法

如果将节点流关闭以后再关闭处理流,会抛出IO异常;
分享到:
评论

相关推荐

    commons-io-2.CHM

    buffer方法:将传入的流进行包装,变成缓冲流。并可以通过参数指定缓冲大小。 2. closeQueitly方法:关闭流。 3. contentEquals方法:比较两个流中的内容是否一致。 4. copy方法:将输入流中的内容拷贝到输出流...

    node-socketio-stream:扩展 socket.io 以支持数据流。 功能与 socket.io-stream 相同,但相关模块已更新

    Socket.IO 的流模块 这个库是对节点模块的更新。 没有进行代码更改,但已更新debug模块以避免现有项目中的安全... 要接收流,您只需用node-socketio-stream包装socket ,然后像往常一样监听任何事件。 服务器: v

    day019-io笔记和代码.rar

    (简单的理解为包装流,就是将字节流包装以下,方便操作文本相关的文件) * 使用场景: * 别人给提供了字节流,而需要处理文本文件,这时候,就需要用转换流转换一下,更方便处理文本文件 * * 作用:...

    ws_stream_wasm-在WASM中使用Websocket的便捷库-Rust开发

    它也有一个方法into_io(),让您获得一个实现AsyncRead / AsyncWrite(功能tokio_io之后的tokio版本)的包装器。 [WsEvent]:对于事件,可用pharos观察[WsMeta](主要用于关闭连接)。 注意:此cr

    Linux高性能服务器编程

    3.5.1 访问不存在的端口 3.5.2 异常终止连接 3.5.3 处理半打开连接 3.6 TCP交互数据流 3.7 TCP成块数据流 3.8 带外数据 3.9 TCP超时重传 3.10 拥塞控制 3.10.1 拥塞控制概述 3.10.2 慢启动和拥塞避免 ...

    nativeflix服务器

    这是的后端包装。 它基本上是通过套接字与应用程序对话,使用磁铁并操纵系统,从而使用户可以部分控制VLC应用程序。 产品特点 将磁铁流到VLC 从opensubtitles API根据给定的语言自动下载最佳字幕 关闭VLC窗口后清除...

    java 面试题 总结

    finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 13、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)的...

    超级有影响力霸气的Java面试题大全文档

    finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 16、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例021 重定向输出流实现程序日志 31 实例022 自动类型转换与强制类型转换 33 2.2 运算符 34 实例023 加密可以这样简单(位运算) 34 实例024 用三元运算符判断奇数和偶数 35 实例025 更精确地使用浮点数 35 实例...

Global site tag (gtag.js) - Google Analytics