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を宣言する必要があります。brnull

  3. 使用する場合を除いて、ファイルを開かないでください。ここで、それは条件付きブロックでそれを開くことを意味します。

  4. ファイルを開くと例外がスローされるbr可能性があるため、初期化されない場合があります。その場合は初期化できませんclosenull最初に確認する必要があります。

于 2010-12-14T00:49:36.500 に答える
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 に答える
2

まず、を使用する必要がありますi<filenames.length。次に、-globsmatchesではなく正規表現を期待します。*使用した式は、の有効な正規表現です[something]ham[something]-それはあなたが意味したことですか?

Filereaderを閉じる必要はないと思います-BRはclose伝播すると思います。しかし、それはチェックする価値があります。前述のように編集します。ifの外で、常にファイルを閉じる必要があります。

于 2010-12-14T00:22:55.763 に答える
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 に答える