我正在从目录的文件中读取内容。我必须根据他们的名字隔离文件,然后阅读他们的内容。当我在没有读取内容的情况下运行代码时,所有文件都列出了特定的文件名,但是当我尝试读取内容时,它只从少数文件中读取内容,实际上只有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();
}
}
答案 0 :(得分: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();
}
}
}
对原始代码的一些一般性评论:
如果您确实需要数组索引,则只使用for
循环。首选for-each循环(即for (filename : filenames) ...
)。
尽可能在最窄的范围内声明变量。在这种情况下,您应该声明我的read
和br
变量,并将其初始化为null
。
除非您打算使用它,否则永远不要打开文件。在这里,这意味着在内部条件块中打开它。
由于打开文件可能会抛出异常,br
可能无法初始化,在这种情况下,您无法close
它。您需要先检查null
。
答案 1 :(得分:2)
您也应关闭FileReader
对象read
。
除非这是家庭作业,否则我建议你看一下commons-io。
编辑#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();
}
}
答案 2 :(得分:2)
首先,您应该使用i<filenames.length
。其次,matches
需要正则表达式,而不是*
- globs。您使用的表达式是[something]ham[something]
的有效正则表达式 - 这是您的意思吗?
我认为你不需要关闭Filereader - 我认为BR的close
会传播。但这值得检查。如上所述 EDIT ,您需要始终关闭if。
答案 3 :(得分: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