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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何羡玉 中级黑马   /  2013-5-18 12:53  /  4018 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 何羡玉 于 2013-5-18 14:49 编辑

我下面的代码如果注释fw.close() 的话 就能取得正常结果,如果不注释fw.close()的话则会抛异常,为什么会跑异常呢,我都是在for循环外面关流的,只有跳出了循环才会关流啊。而且如果我关流的话,只会遍历一部分的.java文件出来,如果我不关,则全部会遍历,这是为什么?????
package enhanceTest;

import java.io.*;

public class Demo9 {
        
        private FileWriter fw=null;
        private File dir=null;
        public Demo9(File dir) throws Exception
        {
                System.out.println("hahahha5");
               
                fw=new FileWriter("e:\\list.txt");
                this.dir=dir;        
        }
        public void listj(File dir) throws Exception
        {
        File[] filess=dir.listFiles();
        for(File files:filess)
        {
                if(files.isDirectory())
                {
                        System.out.println("hahahah1");
                        listj(files);
                }
               
                else{
                if(files.getName().endsWith(".java"))
                {
                fw.write(files.getAbsolutePath());
             fw.write("\r\n");
             fw.flush();     
                }
                }
               
        }
    fw.close();     //如果注释掉,则正常运行,如果不注释就跑异常,为什么???
        }

        public static void main(String[] args) throws Exception {
                // TODO Auto-generated method stub
                File dir=new File("E:\\myworkspace\\day25Test1");
                Demo9 d=new Demo9(dir);
          d.listj(dir);
         
         
        }

}

评分

参与人数 1技术分 +1 收起 理由
殇_心。 + 1

查看全部评分

5 个回复

倒序浏览
本帖最后由 韩秀山 于 2013-5-18 13:52 编辑

IO流,当使用Io连接一个资源文件,对资源进行处理; 处理完必须要关闭流连接。

我举一个例子吧:
    比如:这个文件就是一个房间:使用IO相当与你要去这个房间拿东西。
         在房间里调用。close()就 相当于 把自己锁在屋子里面了。当然会报异常了。
         要在操作完方法之后,在把门锁上。。。
        
回复 使用道具 举报
你这个异常是因为还没有把所有的文件读完就去关流!
你这样子写是读完最里层的一个文件夹中的文件就关一次流!依次这样推,执行完一次方法就关一次!所以会报错!
你要保证是你传入文件夹的下一层目录全部读完之后再关闭流!就不会报错了!
可能说的不是很清楚!给你看一下代码就知道了!
if(this.dir.getAbsoluteFile().equals(dir.getAbsolutePath())){         //这个判断就是保证你读完根目录下的所有文件夹或文件在关流,E:\\myworkspace\\day25Test1
                                                                                      //就是读完这个文件夹中的所有文件夹和文件后才关流,   也就是最后一次递归完执行
                fw.close();
                }

不明白可以再问我!

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
本帖最后由 王盟盟 于 2013-5-18 14:36 编辑

你这个问题是出在递归调用上。如果文件列表里有一个文件夹,程序会递归调用,当程序检查完最里层的文件夹for循环执行完毕,IO流就会被关闭。而这时程序会回到上层调用的位置,IO流已经被关闭,所以会报出java.io.IOException: Stream closed这个异常。简单的说呢,就是你应该将fw.close()流放在listj()外面。也可以按照上面说的,吧fw.close()放在那个if语句里
if(this.dir.getAbsoluteFile().equals(dir.getAbsolutePath())){      
    fw.close();
   }

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
楼上说得对,close方法不注释掉的话,在遍历完一个子文件夹后就关闭了流,但是list方法的递归调用并未结束,它还要去遍历其它的子文件夹啊。
把close方法放在main函数的  d.listj(dir);后面就O了

评分

参与人数 1技术分 +1 收起 理由
Sword + 1 透彻!

查看全部评分

回复 使用道具 举报
按照你的代码,读取完一层文件夹中的文件就会将IO流关闭,当存在多层文件夹时,递归读取完最里层文件夹返回上层时IO流已经不存在了,自然会出现流关闭异常。

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

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