这个代码怎么了?

时间:2010-12-14 00:13:23

标签: java io bufferedreader stringtokenizer

我正在从目录的文件中读取内容。我必须根据他们的名字隔离文件,然后阅读他们的内容。当我在没有读取内容的情况下运行代码时,所有文件都列出了特定的文件名,但是当我尝试读取内容时,它只从少数文件中读取内容,实际上只有10个文件。但该目录包含大约1000个特定名称的文件。我在这里发布代码。

for (i = 0; i <= filenames.length; i++) {
    read = new FileReader("trainfiles/"+filenames[i]);          
    br = new BufferedReader(read);

    if (filenames[i].matches(".*ham.*")) {
        System.out.println("ham:" + filenames[i]);
        while ((lines = br.readLine()) != null) {
            st = new StringTokenizer(lines);
            while (st.hasMoreTokens()) {
                System.out.println(st.nextToken());
            }
        }
        br.close();
    }
}

有谁能告诉我,我在哪里做错了!? 感谢

编辑#1 我做了一些修改,我在这里已被告知,但问题仍然存在,这是代码。

for(i=0;i<=filenames.length;i++){
            read = new FileReader("trainfiles/"+filenames[i]);

            br = new BufferedReader(read);

            if(filenames[i].matches(".*ham.*")){
                System.out.println("ham:"+filenames[i]);

                        while((lines = br.readLine())!= null){
                            st = new StringTokenizer(lines);
                            while(st.hasMoreTokens()){
                                System.out.println(st.nextToken());
                            }

                        }

            }
            br.close();
            read.close();




                        }

编辑#2 现在代码看起来像这样,但是再次......它没有给我我想要的结果。

for (i = 0; i < filenames.length; i++) {
               try {


                if (filenames[i].matches(".*ham.*")) {
                     read = new FileReader("trainfiles/"+filenames[i]);          
                        br = new BufferedReader(read);
                    System.out.println("ham:" + filenames[i]);
                    while ((lines = br.readLine()) != null) {
                        st = new StringTokenizer(lines);
                        while (st.hasMoreTokens()) {
                            System.out.println(st.nextToken());
                        }
                    }
                }
               } finally {

                read.close();
                br.close();
               }
            }

4 个答案:

答案 0 :(得分:3)

我会像这样重写你的代码,看看你得到了什么输出:

for (filename : filenames) {
   if (filename.matches(".*ham.*")) {
      System.out.println("ham:" + filename);

      // reset these to null (where are they declared?)
      read = null;   
      br = null;   
      try {
         read = new FileReader("trainfiles/"+filename);          
         br = new BufferedReader(read);

         while ((lines = br.readLine()) != null) {
            System.out.println(lines);
            // st = new StringTokenizer(lines);
            // while (st.hasMoreTokens()) {
            //    System.out.println(st.nextToken());
            // }
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         if (br != null) br.close();
         if (read != null) read.close();
      }
   } 
}

对原始代码的一些一般性评论:

  1. 如果您确实需要数组索引,则只使用for循环。首选for-each循环(即for (filename : filenames) ...)。

  2. 尽可能在最窄的范围内声明变量。在这种情况下,您应该声明我的readbr变量,并将其初始化为null

  3. 除非您打算使用它,否则永远不要打开文件。在这里,这意味着在内部条件块中打开它。

  4. 由于打开文件可能会抛出异常,br可能无法初始化,在这种情况下,您无法close它。您需要先检查null

答案 1 :(得分:2)

您也应关闭FileReader对象read

除非这是家庭作业,否则我建议你看一下commons-io

编辑#1:我建议在finally块中进行两次关闭操作。

编辑#2:你试过吗?

for (i = 0; i <= filenames.length; i++) {
   try {
    read = new FileReader("trainfiles/"+filenames[i]);          
    br = new BufferedReader(read);

    if (filenames[i].matches(".*ham.*")) {
        System.out.println("ham:" + filenames[i]);
        while ((lines = br.readLine()) != null) {
            st = new StringTokenizer(lines);
            while (st.hasMoreTokens()) {
                System.out.println(st.nextToken());
            }
        }
    }
   } finally {
    br.close();
    read.close();
   }
}

答案 2 :(得分:2)

首先,您应该使用i<filenames.length。其次,matches需要正则表达式,而不是* - globs。您使用的表达式是[something]ham[something]的有效正则表达式 - 这是您的意思吗?

我认为你不需要关闭Filereader - 我认为BR的close会传播。但这值得检查。如上所述 EDIT ,您需要始终关闭if。

之外的文件

答案 3 :(得分:1)

1000多个文件是要阅读的大量文件。如果它无法读取文件,则应抛出异常(IOException具体)。也许在catch块中打印异常消息并将其粘贴到此处。

我不知道StringTokenizer类,但只是在没有StringTokenizer的情况下打印行时代码会出错吗?

另一种选择是使用线程。你有一个文件数组,然后你开始一些读取文件的线程(生产者/消费者问题)。

顺便说一句,您可以使用FileFilter类过滤文件。

http://download.oracle.com/javase/1.4.2/docs/api/java/io/File.html#listFiles%28java.io.FileFilter%29