0

我正在从目录的文件中读取内容。我必须根据文件的名称隔离文件,然后阅读它们的内容。当我只运行代码而不读取内容时,所有文件都以特定文件名列出,但是当我尝试读取内容时,它只从几个文件中读取内容,实际上只有 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

4 回答 4

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. 在尽可能窄的范围内声明变量。read在这种情况下,您应该br在我将它们初始化为null.

  3. 除非您要使用文件,否则切勿打开文件。在这里,这意味着在条件块内打开它。

  4. 由于打开文件可能会引发异常,br因此可能无法初始化,在这种情况下您不能close这样做。你需要先检查一下null

于 2010-12-14T00:49:36.500 回答
2

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

我认为您不需要关闭 Filereader - 我认为 BR 会close传播。但这值得检查。如前所述编辑,您需要始终在 if 之外关闭文件。

于 2010-12-14T00:22:55.763 回答
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();
   }
}
于 2010-12-14T00:19:35.653 回答
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

于 2010-12-14T00:33:20.453 回答