Java BufferedReader在循环之前检查循环的下一行

时间:2012-02-08 17:21:08

标签: java loops bufferedreader

我正在解析.cvs文件。 对于每个cvs行,我创建一个带有解析值的对象,并将它们放入一个集合中。

在将对象放入地图并循环到下一个之前,我需要检查下一个cvs的行是否与实际对象相同,但具有不同的特定属性值。

为此,我需要检查缓冲区的下一行,但是将循环的缓冲区保持在相同的位置。

例如:

BufferedReader input  = new BufferedReader(new InputStreamReader(new FileInputStream(file),"ISO-8859-1"));
String line = null;

while ((line = input.readLine()) != null) {
    do something

    while ((nextline = input.readLine()) != null) { //now I have to check the next lines
       //I do something with the next lines. and then break.
    }
    do something else and continue the first loop.
}

3 个答案:

答案 0 :(得分:8)

  1. 您可以使用BufferedReader.mark(int)标记当前位置。要返回到您致电BufferedReader.reset()的位置。 mark的参数是“预读限制”;如果在读取超过限制后尝试reset(),则可能会出现IOException。

  2. 或者您可以改为使用RandomAccessFile

    // Get current position
    long pos = raf.getFilePointer();
    // read more lines...
    // Return to old position
    raf.seek(pos);
    
  3. 或者您可以使用允许unread字符的PushbackReader。但有一个缺点:PushbackReader没有提供readLine方法。

答案 1 :(得分:1)

考虑使用已经像OpenCSV那样的东西。我认为您可以为它创建类似custom mapping strategy的内容。

答案 2 :(得分:1)

您也可以使用嵌套的do ... while循环执行此操作,而无需从流中重新读取任何内容:

public void process(File file) throws Exception {
    BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(file), "ISO-8859-1"));
    String batchParent = input.readLine(); // read the first line in the file, this is a new batch
    String batchChild;
    do {
        currentBatch = new Batch(batchParent);
        do {
            batchChild = input.readLine();
        } while (addToBatchIfKeysMatch(batchParent, batchChild));
        // if we break out of the inner loop, that means batchChild is a new parent
        // assign it to batchParent and continue the outer loop
        batchParent = batchChild;
    } while (batchParent != null);
}

private boolean addToBatchIfKeysMatch(final String batchParent, final String batchChild) {
    if (batchChild != null && keysMatch(batchParent, batchChild)) {
        currentBatch.add(batchChild);
        return true;
    } else {
        return false;
    }
}

关键是只读取每个文件并将其作为内部循环中的子行处理,或者将parentLine设置为新读取的值并继续外部循环。