详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt381

问题:

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

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

问题(1)解释:

如下例子代码:

1
2
3
  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方法关闭其装饰的内层流,验证例子:

1
2
3
4
5
6
7
8
9
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)方式关闭流,可以逐个关闭流(可能大家比较习惯吧)

如下例子:

1
2
3
4
5
6
7
8
9
10
11
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)

如下例子:

1
2
3
4
5
6
7
8
9
10
 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异常;

Java IO包装流如何关闭的更多相关文章

  1. Java IO包装流如何关闭?

      问题: (1)JAVA的IO流使用了装饰模式,关闭最外面的流的时候会自动调用被包装的流的close()方吗? (2)如果按顺序关闭流,是从内层流到外层流关闭还是从外层到内存关闭? 问题(1)解释: ...

  2. Java IO 转换流 字节转字符流

    Java IO 转换流 字节转字符流 @author ixenos 字节流 输入字节流:---------| InputStream 所有输入字节流的基类. 抽象类.------------| Fil ...

  3. Java IO 过滤流 BufferedInput/OutputStream

    Java IO 过滤流 BufferedInput/OutputStream @author ixenos 概念 BufferedInput/OutputStream是实现缓存的过滤流,他们分别是Fi ...

  4. Java IO 节点流 FileInput/OutputStream

    Java IO 节点流 FileInput/OutputStream @author ixenos 节点流之 文件流 文件读写是最常见的I/O操作,通过文件流来连接磁盘文件,读写文件内容 1.文件的读 ...

  5. Java IO 节点流 ByteArrayInput/OutputStream

    Java IO 节点流 ByteArrayInput/OutputStream @author ixenos ByteArrayInputStream 包含一个内部缓冲区(字节数组byte[]),该缓 ...

  6. Java IO: 字符流的Buffered和Filter

    作者: Jakob Jenkov  译者: 李璟(jlee381344197@gmail.com) 本章节将简要介绍缓冲与过滤相关的reader和writer,主要涉及BufferedReader.B ...

  7. Java IO: 字符流的Piped和CharArray

    作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) 本章节将简要介绍管道与字符数组相关的reader和writer,主要涉及PipedReader.Pip ...

  8. Java Io 字符流

    Java Io 字符流包含: 1. InputStreamReader  它是由byte流解析为char流,并且按照给定的编码解析. 2. OutputStreamWrite  它是char流到byt ...

  9. eclipse连接远程Hadoop报错,Caused by: java.io.IOException: 远程主机强迫关闭了一个现有的连接。

    eclipse连接远程Hadoop报错,Caused by: java.io.IOException: 远程主机强迫关闭了一个现有的连接.全部报错信息如下: Exception in thread & ...

随机推荐

  1. Android文件上传与下载

    文件上传与下载 文件上传 -- 服务端 以Tomcat为服务器,Android客服端访问Servlet,经Servlet处理逻辑,最终将文件上传,这里就是简单模拟该功能,就将文件上传到本机的D:\\u ...

  2. 安装完jdk配置环境变量

    (1)新建->变量名"JAVA_HOME",变量值"C:\Java\jdk1.8.0_05"(即JDK的安装路径) (2)编辑->变量名" ...

  3. Consul文档简要整理

    什么是Consul? Consul是一个用来实现分布式系统的服务发现与配置的开源工具.他主要由多个组成部分: 服务发现:客户端通过Consul提供服务,类似于API,MySQL,或者其他客户端可以使用 ...

  4. 【有意思的BUG】分享按钮 分享功能

    [分享按钮]是一个常见的功能,你可以把看到的有意思的东西分享到自己的BLOG.朋友圈之类的地方. 但是,分享出去的文本(也可以包含图片)在每个目标网站上面的格式并不是统一的,所以就存在了美感的三六九等 ...

  5. hibernate中对象的3种状态----瞬时态、持久态、脱管态

    Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...

  6. Maven注意事项

    Maven好处: 1.依赖管理:对jar包统一管理 2.项目构建:项目编码完成后,对项目进行编译.测试.打包.部署,实现项目一键发布1.配置环境变量    注意:maven工具必须有jdk环境.并且: ...

  7. HDU 3682 To Be an Dream Architect:查重【三维坐标系中点在实数上的映射】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3682 题意: 有一个n*n*n的立方体,左下角坐标为(1,1,1),接下来进行m次操作. 每个操作形如 ...

  8. MySQL数据库—日期与时间函数

    一. 日期和时间函数 函数的概念:按指定格式输入参数,返回正确结果的运算单元 1. 返回当前日期:curdate() current_date() current_date()+0可以将当前日期转换为 ...

  9. Linux下C程序的存储空间布局

    一个程序本质上都是由 BSS 段.data段.text段三个组成的.可以看到一个可执行程序在存储(没有调入内存)时分为代码段.数据区和未初始化数据区三部分. BSS段(未初始化数据区):在采用段式内存 ...

  10. 利用URL protocol在网页打开本地exe

    Registering the Application Handling the Custom URI Scheme To register an application to handle a pa ...