2010-12-14 23 views
0

ディレクトリのファイルから内容を読み取っています。私はファイルを名前に応じて分離し、その内容を読まなければなりません。コンテンツを読み込まずにコードを実行すると、すべてのファイルが特定のファイル名にリストされますが、コンテンツを読み込もうとすると、ほんのわずかなファイルからコンテンツが読み込まれます。しかし、ディレクトリには約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(); 
    } 
} 

誰かが私に間違っていると教えてもらえますか?
おかげ

EDIT#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(); 




         } 

EDIT#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(); 
       } 
      } 
+0

何の名前はspam.txtているいくつかのファイル、私は言葉だけのハムとスパムを探して、そこに内容を読んでいますが – Maverick

+0

は、ファイルのすべてよろしいです..合計2450個のファイルにあります。..はありません読んでいる?ループの前にファイル名を印刷してみてください。 – javamonkey79

+0

はい、単純に印刷するとすべてのファイルが出力されますが、読み込むコードを書き込むと正確な出力が得られません。 – Maverick

答えて

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. 可能な限り最も狭い範囲の変数を宣言します。この場合、私はnullに初期化するあなたのreadbr変数を宣言する必要があります。

  3. ファイルを使用する場合を除き、決してファイルを開かないでください。ここでは、の中にという条件ブロックを開きます。

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

+0

私はそれをチェックさせてください – Maverick

+0

まあ...私はちょうどメモ帳にプログラムを貼り付けてコピーして、それを保存しました。 javaファイルを作成してコマンドプロンプトでテストしてみましたが、今はecpliseに表示されていない別のファイル名を取得しています。コマンドプロンプトの出力をファイルに取り込む方法はありますか?!!!! – Maverick

+1

ほとんどのOSには、ファイルにリダイレクトする方法がいくつかあります。たとえば 'java ar g1 arg2など> someFile' –

2

あなたにも、あなたのFileReaderオブジェクトreadを閉じる必要があります。

これが宿題でない限り、commons-ioをご覧ください。

EDIT#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(); 
    } 
} 
+0

+1: 'br'も閉じなければなりません。現在、ファイル名がそのパターンと一致する場合にのみ閉じます。 –

+0

私はそれをしましたが、それと同じ問題です。名前がハムであるファイル全体を読むことができません。 – Maverick

+0

@mad_programmer:変更したコードを閉じるとともに表示します。 –

2

まず、i<filenames.lengthを使用してください。次に、matchesは、正規表現ではなく、*のグロブを必要とします。使用した表現は[something]ham[something]の有効な正規表現です - これは意味ですか?

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

+0

私は<= to Maverick

+0

。しかし、私が始めたときに、シェルスタイルのファイル名のグロブを使用しようとしましたが、おそらくそのパターンを[何か] .ham [何か]とドットにマッチさせようとしました。あなたがそれがREだったと理解したことを確認するだけです。 – Robert

+1

または、より良いことに、ファイルを開くには、 'if'をインクルードします。ファイルのオープン/クローズは、正規表現のチェックに比べて実際には高価です。 –

1

1000+ファイルは、読み込むファイルがたくさんあります。ファイルを読み取れない場合は、例外(IOExceptionを特定)をスローする必要があります。おそらく例外メッセージをキャッチブロックに印刷して、ここに貼り付けてください。

StringTokenizerクラスはわかりませんが、StringTokenizerを使用しないで行を印刷するとエラーが発生しますか?

スレッドを使用することもできます。あなたはファイルの配列を持っていて、次にファイルを読み込むスレッドをいくつか起動します(プロデューサ/コンシューマの問題)。

ところで、FileFilterクラスでファイルをフィルタリングすることができます。

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

+0

Well ..それはなんのエラーもありません。 – Maverick

+0

あなたのコードはStringTokenizerなしで動作しますか? –

+0

実際に私の割り当て用のスパムフィルタを構築しています。 – Maverick

関連する問題