André Perazzi
André Perazzi

Reputation: 1039

Java BufferedReader check next lines of a loop before looping

I'm parsing a .cvs file. For each line of the cvs, I create an object with the parsed values, and put them into a set.

Before putting the object in the map and looping to the next, I need to check if the next cvs's line is the same object as the actual, but with a particular property value different.

For that, I need check the next lines of the buffer, but keep the loop's buffer in the same position.

For example:

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.
}

Upvotes: 7

Views: 9040

Answers (2)

Joni
Joni

Reputation: 111299

  1. You can mark the current position using BufferedReader.mark(int). To return to the position you call BufferedReader.reset(). The parameter to mark is the "read ahead limit"; if you try to reset() after reading more than the limit you may get an IOException.

  2. Or you could use RandomAccessFile instead:

    // Get current position
    long pos = raf.getFilePointer();
    // read more lines...
    // Return to old position
    raf.seek(pos);
    
  3. Or you could use PushbackReader which allows you to unread characters. But there's the drawback: PushbackReader does not provide a readLine method.

Upvotes: 8

Sam Barnum
Sam Barnum

Reputation: 10714

You can also do this with nested do…while loops, without re-reading anything from your stream:

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;
    }
}

The key is to just read each file and either process it as a child line in the inner loop, or set the parentLine to the newly read value and continue the outer loop.

Upvotes: 1

Related Questions