A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 崔朋朋 中级黑马   /  2012-10-5 11:52  /  2854 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 崔朋朋 于 2012-10-5 17:57 编辑

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class IOTest {

        public static void main(String[] args) throws Exception {
                   FileOutputStream fos = new FileOutputStream("d:\\test.txt");
                   OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
                   BufferedWriter bw = new BufferedWriter(osw);
                   bw.write("java IO 流的关闭顺序测试");
                  
                  //这种关闭顺序会报异常: java.io.IOException: Stream closed                                 
                   fos.close();
                   osw.close();
                   bw.close();

                   //这种关闭顺序则不会报异常                                 
                   //bw.close();
                   //osw.close();
                   //fos.close();
                }
}

所有打开的IO流必须按照第二种方式依次关闭吗?    为啥第一种会报 Stream closed 异常?

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
是的,要依次关,第一种bw不是要写入数据进fos中的"d:\\test.txt"文件么?你先将fos关闭了,当关闭bw的时候还要flush刷新,这时文件都不在了就不能刷新了~!

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
l楼上很给力呀,打个酱油
回复 使用道具 举报
一般情况下是:先打开的后关闭,后打开的先关闭
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
如果将节点流关闭以后再关闭处理流,会抛出IO异常

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
public class IOTest {

        public static void main(String[] args) throws Exception {
                   FileOutputStream fos = new FileOutputStream("d:\\test.txt");
                   OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); //fos流对象被传入了这里,也就是使用了 fos 流对象
                   BufferedWriter bw = new BufferedWriter(osw); //osw流被传入了这里,也就是使用了osw 对象。                  
                   bw.write("java IO 流的关闭顺序测试");
                  
                  //这种关闭顺序会报异常: java.io.IOException: Stream closed                                 
                   fos.close();   
                   osw.close();   
                   bw.close();    //这样关当然会报错了,自己要调用别的流时,却发现别的流被关掉了。被调用的要后关。

                   //这种关闭顺序则不会报异常                                 
             //bw.close();
                   //osw.close();
                   //fos.close();
                }
}

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
缓冲流关闭的是被其包装流的资源,这是BufferedWriter的源代码:
public BufferedWriter(Writer out) {
        this(out, defaultCharBufferSize);
    }
这是构造函数,再看看起close函数
public void close() throws IOException {
        synchronized (lock) {
            if (out == null) {
                return;
            }
            try {
                flushBuffer();
            } finally {
                out.close();                out = null;
                cb = null;
            }
        }
    }
看的出来但你先调用缓冲流之后它释放的就是被它包装之后流的资源,如果你释放之前就已经对其资源就像释放了,而且out 是!=null 要不然就不会报错了,我想找一下fos和osw的close源代码,可惜fos是调用的本地方法,没找着,只能这么推测了。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马