2010-12-14 6 views
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(); 
    } 
} 

Может ли кто-нибудь сказать мне, где я делаю неправильно !?
благодаря

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, я просто ищу слова ветчины и спам и читать там содержание .. есть в общих сложности 2450 файлов .. – Maverick

+0

уверен Вы не все файлы читаются? Попробуйте распечатать имена файлов до цикла. – 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. Только использование a for, если вам действительно нужен индекс массива. Предпочтительно для каждого цикла (то есть for (filename : filenames) ...).

  2. Объявлять переменные в самом узком объеме. В этом случае вы должны объявить переменные read и br, где я инициализирую их до null.

  3. Никогда не открывайте файл, если вы его не используете. Здесь это означает его открытие внутри условный блок.

  4. С момента открытия файла может возникнуть исключение, br может не получиться инициализированным, и в этом случае вы не сможете его получить. close. Сначала необходимо проверить на null.

+0

ok дайте мне проверить его – Maverick

+0

ну ... Я просто скопировал программу в блокнот и сохранил ее как java-файл и протестировал его в командной строке, и теперь я получаю разные имена файлов, которые не были показаны в ecplise. Я сомневаюсь, что это ограничение консоли в eclipse, которое не может отображать большой результат. Даже командная строка делает то же самое. Есть ли способ взять вывод командной строки в файл? !!!! – Maverick

+1

в большинстве ОС есть способ перенаправления в файл: например, 'java ar g1 arg2 и т. д.> someFile'. –

2

Вы должны закрыть FileReader объект read, а также.

Если это не домашнее задание, я бы также предложил вам взглянуть на commons-io.

РЕДАКТИРОВАТЬ # 1: Я бы предложил выполнить обе операции закрытия в блоке finally.

EDIT # 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 ожидает регулярное выражение, а не * -globs. Вы использовали правильное выражение для [something]ham[something] - это то, что вы имели в виду?

Я не думаю, что вам нужно закрыть Filereader - я думаю, что BR's close распространяется вверх. Но это стоит проверить. EDIT Как уже упоминалось, вам нужно всегда закрывать файл, вне if.

+0

ok я удалил <= до Maverick

+0

Понял. Но когда я начал, я попытался использовать shell-style filename globbing и, вероятно, попробовал бы этот шаблон, чтобы он соответствовал [something] .ham. [Something], с точками. Просто подтвердив, что вы поняли, что это RE. – Robert

+1

Или, еще лучше, только откройте файл _inside_ 'if'. Открытие/закрытие файла действительно дорого по сравнению с проверкой регулярного выражения. –

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

+0

Ну .. это не дает никакой ошибки как таковой. – Maverick

+0

и работает ли ваш код без StringTokenizer? –

+0

Фактически я создаю спам-фильтр для своего задания. , Мне нужно загрузить содержимое файла с ветчиной и спамом в отдельной хеш-таблице. Мне нужен StringTokenizer для этого. – Maverick

Смежные вопросы