我是java的新手。我试图迭代几个.txt
文件来比较文件的一行到第二个文件的每一行。这些是我的两个文件:listread.txt
和csvread.txt
。
以下是我正在使用的代码:
try {
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
String csvItem, listItem;
int count =0;
while((csvItem = csvReader.readLine()) != null){
System.out.println("before second loop:"+csvItem);
while ((listItem = listReader.readLine())!= null) {
System.out.println("list Item: "+listItem.toLowerCase().split("¬")[1]);
System.out.println("csv Item: "+csvItem.toLowerCase());
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}
}
}catch(Exception e){
e.printStackTrace();
}
当我运行此选项时,只会将csvread.txt
中的第一行(存储在变量csvItem
中)与listread.txt
中的所有行进行比较。以下是输出示例:
before second loop:Record Category
list item: provisions
csv Item: record category
list item: request category
csv Item: record category
list item: elevator
csv Item: record category
list item: assessment
csv Item: record category
list item: associates
csv Item: record category
list item: score
csv Item: record category
list item: attachments
csv Item: record category
它只使用list.txt
文件的第一行迭代csvread.txt
文件的所有行。不会移到csvread.txt
的第二行,程序会在最后一行中抛出错误:
java.lang.ArrayIndexOutOfBoundsException: 1
at test.main(test.java:52)
指的是System.out.println("list item: "+listItem.toLowerCase().split("¬")[1]);
行。这句话与我猜的迭代无关。不知道为什么会抛出这个错误..
但是,当我注释掉第二个for循环时,它会在csvread.txt
文件中的所有行上进行精细迭代。这是一个示例输出,只有第一个while循环和第二个循环注释掉:
before second loop:Record Category
before second loop:Type
before second loop:Name
before second loop:State
before second loop:Number
before second loop:ID (Self)
before second loop:Parent
before second loop:Title
仅当存在嵌套循环时才会出现此问题。当有一个循环时,根本没有问题。有人可以对这种奇怪的行为有所了解吗?我该如何克服它?
修改
我添加了一个if
条件来检查该行是否包含¬
,因为我在该字符上拆分了该行:
if(listItem.contains("¬")){
System.out.println("list item: "+listItem.toLowerCase().split("¬")[1]);
System.out.println("csv Item: "+csvItem.toLowerCase());
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}
不,我不再得到例外。但是,这种行为仍然很奇怪。这是添加if
后的输出:
before second loop:Record Category
list item: provisions
csv Item: record category
list item: request category
csv Item: record category
list item: elevator
csv Item: record category
list item: assessment
csv Item: record category
list item: associates
csv Item: record category
list item: score
csv Item: record category
list item: attachments
csv Item: record category
before second loop:Type
before second loop:Name
before second loop:State
before second loop:Number
before second loop:ID (Self)
before second loop:Parent
before second loop:Title
现在正在csvread.txt
中迭代其他元素,但除了第一个元素之外,与listread.txt
中的行的比较并没有变化。
任何帮助将不胜感激。谢谢!
答案 0 :(得分:0)
使用嵌套循环时,内部循环会完全执行。然后执行控制来自内部循环并开始外部循环的下一次迭代。因此,如果要逐行比较两个文件的内容,则不应该有任何内部循环。以下是您在此案例中可能尝试执行的示例代码。虽然,我还没有测试过它。
try {
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
String csvItem, listItem;
int count =0;
while((csvItem = csvReader.readLine()) != null){
System.out.println("before second loop:"+csvItem);
listItem = listReader.readLine();
if (listItem != null){
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}else{
//The listItem has no more lines to compare, so ending the process.
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
我希望这会有所帮助。
注意:上面给出的答案是相信要求是逐行比较两个文件的内容。
答案 1 :(得分:0)
您对
的访问权限listItem.toLowerCase().split("¬")[1]
很关键,因为你总是希望所有的线都有你的“¬”。如果不是这种情况,你的分割将不会返回一个数组,你访问位置[1]的returend数组失败并返回IndexOutOfBounds ....
答案 2 :(得分:0)
扩展了我在第一次迭代后指向文件末尾的listReader
的评论。 BufferedReader
没有提供移动文件指针的机制,因此一个简单的方法是将listReader
的创建移到外部循环中:
try {
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
// BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
String csvItem, listItem;
int count =0;
while((csvItem = csvReader.readLine()) != null){
System.out.println("before second loop:"+csvItem);
BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
while ((listItem = listReader.readLine())!= null) {
System.out.println("list Item: "+listItem.toLowerCase().split("¬")[1]);
System.out.println("csv Item: "+csvItem.toLowerCase());
if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
count++;
}
}
}
}catch(Exception e){
e.printStackTrace();
}
所以每次迭代都会有一个新的listReader
从文件的顶部开始。
但这可能是I / O太多了。如果list.txt的大小不是太大,那么可能只读一次,解析它,并存储在Set<String>
中以供以后比较:
try (BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"))) {
String listItem = null;
Set<String> listItems = new HashSet<>();
while ((listItem = listReader.readLine()) != null) {
listItems.add(listItem.toLowerCase().split("¬")[1]);
}
String csvItem;
int count = 0;
while ((csvItem = csvReader.readLine()) != null) {
System.out.println("before second loop:" + csvItem);
for (String item : listItems) {
System.out.println("list Item: " + item);
System.out.println("csv Item: " + csvItem.toLowerCase());
if (item.contains(csvItem.toLowerCase())) {
count++;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
还转移到试用资源,以确保csvReader
和listReader
正确关闭。