Вопрос

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

Решение

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

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 первый.

Другие советы

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

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

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

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

Редактировать # 1: Я бы предложил сделать оба тесные операции в наконец-то блоке.

Редактировать # 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();
   }
}

1000+ файлов - это много файлов для чтения. Если он не может прочитать файл, он должен выбрасывать исключение (IOException, чтобы быть конкретным). Возможно распечатать сообщение об исключении в блоке Catch Catch и вставьте его здесь.

Я не знаю класс StringTokleizer, но дает ли код ошибки, когда вы просто распечатаете линию без StringTokerizer?

Другой вариант - использовать потоки. У вас есть массив файлов, а затем вы начинаете несколько потоков, которые читают файл (проблема производителя / потребителей).

Кстати, вы можете фильтровать файлы с классовым файломFilter.

http://download.orcle.com/javase/1.4.2/docs/api/java/io/file.html#listfiles%28java.io.filefilter%29.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top