添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

转载1: Java IO流关闭问题的深入研究
转载2: Java IO包装流如何关闭?(关闭顺序)

两种分析过程不一样,但是结论相差不大:
(个人认为转载1分析的比较透彻)

一般情况下是:先打开的后关闭,后打开的先关闭;
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
如果将节点流关闭以后再关闭处理流,会抛出IO异常;

(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();

问题(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();

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

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

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

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

如果将节点流关闭以后再关闭处理流,会抛出IO异常;

转载1:Java IO流关闭问题的深入研究 转载2:Java IO包装流如何关闭?(关闭顺序)两种分析过程不一样,但是结论相差不大: (个人认为转载1分析的比较透彻)一般情况下是:先打开的后关闭,后打开的先关闭;另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候
Java关闭一直是个让人头疼的问题,很多人要么就是忘记关闭,要么就是对关闭顺序模糊不清,实际开发过程中,也常常因为关闭导致应用程序出现各种莫名奇妙的Bug。所以本篇整理出了Java中Stream(主要指IO流,非指Java1.8中式处理)关闭中常见的几种情况,并通过自己测试和查看源码等方式给出证明过程,下面开始。 1.各种中存在包装关系,如何关闭 try { InputStream inputStream = new FileInputStream("D:\\test\\te
包装是没有无参的,必须传递对应的基础。完整代码: 之前使用的 IO 中,都是跟磁盘直接进行交互,这种交互方式效率比较低下。现在使用的是有缓冲区,从磁盘直接读取到内存中,再从内存中一次性读取出来: 看起来这种方式好像更麻烦了,但是这种方式实际效率更高。 2、包装关闭资源(close
public static void main(String[] args) throws IOException { FileOutputStream out = null; FileInputStream in = null; BufferedOutputStream bos = null; BufferedInputStream...
File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 的分类介绍:http://www.cnblogs.com/ysocean/p/6854098.html Java IO 字节输入输出:http://www.cnblogs.com/ysocean/p/6854541.html Java IO 字符输入输出:https://i.cnblogs.com/EditPosts.aspx?postid=6859242 GC运行的时间点是不确定的(因为是一条单独存在的线程),所以很多时候你不能直接控制什么时候发生GC。 这个带来的问题有两点 一个是`有时候你的内存不足需要立刻回收而GC并不会立刻运行` 另外一个是因为`GC运行期间会占用大量系统资源所以某些情况下你会希望把它推后,或者干脆关掉以便根据性能需求在合式的时候手动执行`。 另外,GC只能回收内存。至于各种stream之类,他们接下来一般还开启了各种其他的系统资源,比如文件,比如输入输出设备(键盘/屏幕等),等等。 而这些设备第一是不能自