码迷,mamicode.com
首页 > 编程语言 > 详细

java IO包装流如何关闭

时间:2018-04-07 12:59:13      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:sed   ati   throw   技术分享   static   close   模式   节点   buffered   

问题:

(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异常;

 

转自http://www.cnblogs.com/qqzy168/p/3670915.html

java IO包装流如何关闭

标签:sed   ati   throw   技术分享   static   close   模式   节点   buffered   

原文地址:https://www.cnblogs.com/winkey4986/p/8732559.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!