Что не так с этим кодом?
-
09-10-2019 - |
Вопрос
Я читаю содержимое из файлов каталога. Я должен отделить файлы в соответствии с их именами, а затем прочитать их содержимое. Когда я запускаю код просто без числа содержимого, все файлы перечислены в указанном конкретном имени файла, но когда я пытаюсь прочитать содержимое, он читает содержимое от только нескольких файлов, на самом деле всего 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();
}
}
}
Некоторые общие комментарии к вашему оригиналу:
Используйте только A.
for
Цикл Если вам действительно нужен индекс массива. Предпочитаю для каждого цикла (то естьfor (filename : filenames) ...
).Объявите переменные в самых узких возможностях. В этом случае вы должны объявить
read
иbr
переменные, где я их инициализируюnull
.Никогда не открывайте файл, если вы не будете использовать его. Здесь, это значит открыть его внутри Условный блок.
С открытия файла может бросить исключение,
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.