同一对象的迭代器不能独立运行

时间:2017-07-31 09:26:22

标签: java iterator opencsv

我有一个比较两个csv文件内容的方法。我使用CSVReader.iterator()而不是用CSVReader.readNext()加载每一行,因为我在比较文件中的行数时遇到了一些问题。该方法看起来像这样(检查第一条评论 - 这是一个'黑客',我曾经做过一个解决方法,但我很好奇为什么没有它就行不通):

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,这没有任何意义,因为它们应该独立工作。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您不能使用相同的流来两次读取内容。你应该这样做:

byte[] content = "aaa,ddd,aaa".getBytes(_CHARSET);
A = new ByteArrayInputStream(content);
B = new ByteArrayInputStream(content);;

答案 1 :(得分:0)

这是因为当您创建CSVReader时,他会在构造函数中执行CSVIterator并执行next()。你在同一个对象上创建两个读者 - 第一个读者做next(),下一行为String[],第二个读者有任何行 - 因为首先有它。

CsvIterator在每个读者上创建:

  public CSVIterator(CSVReader reader) throws IOException {
     this.reader = reader;
     nextLine = reader.readNext();
  }

这是你问题的答案。