что не так с этим кодом? - PullRequest
       17

что не так с этим кодом?

0 голосов
/ 14 декабря 2010

Я читаю содержимое из файлов каталога. Я должен разделить файлы по их именам, а затем прочитать их содержимое. Когда я запускаю код просто без чтения содержимого, все файлы перечислены с определенным именем файла, но когда я пытаюсь прочитать содержимое, он читает содержимое только из нескольких файлов, фактически только из 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 ]

3 голосов
/ 14 декабря 2010

Я бы переписал ваш код следующим образом и посмотрел бы, какой вывод вы получите:

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 (filename : filenames) ...).

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

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

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

2 голосов
/ 14 декабря 2010

Прежде всего вы должны использовать i<filenames.length.Во-вторых, matches ожидает регулярное выражение, а не * -глоб.Вы использовали правильное регулярное выражение для [something]ham[something] - это то, что вы имели в виду?

Не думаю, что вам нужно закрывать Filereader - я думаю, что BR * close распространяется вверх.Но это стоит проверить. РЕДАКТИРОВАТЬ , как уже упоминалось, вы должны всегда закрывать файл, вне if.

2 голосов
/ 14 декабря 2010

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

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

EDIT # 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();
   }
}
1 голос
/ 14 декабря 2010

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

...