同一对象的迭代器不独立运行
Iterators of the same object do not operate independently
我有一个比较两个 csv 文件内容的方法。我使用 CSVReader.iterator() 而不是用 CSVReader.readNext() 加载每一行,因为我在比较文件中的行数时遇到了一些问题。该方法看起来像这样(检查第一条评论 - 那是 'hack' 我曾经做过一个解决方法,但我很好奇为什么没有它它就不能工作):
public int compareTwoFiles(InputStream fileA, InputStream fileB) throws IOException {
// I used this to fix the problem
/*if (fileA == fileB) {
return 1;
}*/
CSVReader readerA = new CSVReader(new InputStreamReader(fileA));
CSVReader readerB = new CSVReader(new InputStreamReader(fileB));
// empty file flag
boolean empty = true;
Iterator<String[]> iteratorA = readerA.iterator();
Iterator<String[]> iteratorB = readerB.iterator();
while (iteratorA.hasNext() && iteratorB.hasNext()) {
String[] currentLineA = iteratorA.next();
String[] currentLineB = iteratorB.next();
// if lines length doesn't match - return 0
if (currentLineA.length != currentLineB.length) {
return 0;
}
else {
for (int index = 0; index < currentLineA.length; index++) {
// if the already checked part of file is empty, check if current cells are empty
if (empty) {
// if one of the fields isn't empty, change empty flag
if (!currentLineA[index].equals("") || !currentLineB[index].equals("")) {
empty = false;
}
}
// if fields don't match - return 0
if (!currentLineA[index].equals(currentLineB[index])) {
return 0;
}
}
}
}
if (iteratorA.hasNext() ^ iteratorB.hasNext()) {
return 0;
}
if (empty) {
return -1;
}
return 1;
}
这是失败的测试:
@Test
public void testSameNonEmptyFile() throws IOException {
A = new ByteArrayInputStream("aaa,ddd,aaa".getBytes(_CHARSET));
B = A;
Assert.assertTrue(p.compareTwoFiles(A, B) == 1);
}
当我试图手动调试它时,结果发现 iteratorA 指向一个 String[] 但 iteratorB 为 null,这没有任何意义,因为它们应该独立工作。有什么想法吗?
您不能使用同一个流来读取内容两次。你应该这样做:
byte[] content = "aaa,ddd,aaa".getBytes(_CHARSET);
A = new ByteArrayInputStream(content);
B = new ByteArrayInputStream(content);;
这是因为当你创建 CSVReader
他在构造函数中执行 CSVIterator
并执行 next()
。您在同一个对象上创建了两个 reader,第一个 reader 执行 next()
,下一行为 String[]
,第二个 reader 没有任何行- 因为首先拥有它。
CsvIterator 在每个 reader do:
上创建
public CSVIterator(CSVReader reader) throws IOException {
this.reader = reader;
nextLine = reader.readNext();
}
这就是你问题的答案。
我有一个比较两个 csv 文件内容的方法。我使用 CSVReader.iterator() 而不是用 CSVReader.readNext() 加载每一行,因为我在比较文件中的行数时遇到了一些问题。该方法看起来像这样(检查第一条评论 - 那是 'hack' 我曾经做过一个解决方法,但我很好奇为什么没有它它就不能工作):
public int compareTwoFiles(InputStream fileA, InputStream fileB) throws IOException {
// I used this to fix the problem
/*if (fileA == fileB) {
return 1;
}*/
CSVReader readerA = new CSVReader(new InputStreamReader(fileA));
CSVReader readerB = new CSVReader(new InputStreamReader(fileB));
// empty file flag
boolean empty = true;
Iterator<String[]> iteratorA = readerA.iterator();
Iterator<String[]> iteratorB = readerB.iterator();
while (iteratorA.hasNext() && iteratorB.hasNext()) {
String[] currentLineA = iteratorA.next();
String[] currentLineB = iteratorB.next();
// if lines length doesn't match - return 0
if (currentLineA.length != currentLineB.length) {
return 0;
}
else {
for (int index = 0; index < currentLineA.length; index++) {
// if the already checked part of file is empty, check if current cells are empty
if (empty) {
// if one of the fields isn't empty, change empty flag
if (!currentLineA[index].equals("") || !currentLineB[index].equals("")) {
empty = false;
}
}
// if fields don't match - return 0
if (!currentLineA[index].equals(currentLineB[index])) {
return 0;
}
}
}
}
if (iteratorA.hasNext() ^ iteratorB.hasNext()) {
return 0;
}
if (empty) {
return -1;
}
return 1;
}
这是失败的测试:
@Test
public void testSameNonEmptyFile() throws IOException {
A = new ByteArrayInputStream("aaa,ddd,aaa".getBytes(_CHARSET));
B = A;
Assert.assertTrue(p.compareTwoFiles(A, B) == 1);
}
当我试图手动调试它时,结果发现 iteratorA 指向一个 String[] 但 iteratorB 为 null,这没有任何意义,因为它们应该独立工作。有什么想法吗?
您不能使用同一个流来读取内容两次。你应该这样做:
byte[] content = "aaa,ddd,aaa".getBytes(_CHARSET);
A = new ByteArrayInputStream(content);
B = new ByteArrayInputStream(content);;
这是因为当你创建 CSVReader
他在构造函数中执行 CSVIterator
并执行 next()
。您在同一个对象上创建了两个 reader,第一个 reader 执行 next()
,下一行为 String[]
,第二个 reader 没有任何行- 因为首先拥有它。
CsvIterator 在每个 reader do:
上创建 public CSVIterator(CSVReader reader) throws IOException {
this.reader = reader;
nextLine = reader.readNext();
}
这就是你问题的答案。