问题
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.
}
回答1:
You can mark the current position using BufferedReader.mark(int). To return to the position you call
BufferedReader.reset()
. The parameter tomark
is the "read ahead limit"; if you try toreset()
after reading more than the limit you may get an IOException.Or you could use RandomAccessFile instead:
// Get current position long pos = raf.getFilePointer(); // read more lines... // Return to old position raf.seek(pos);
Or you could use PushbackReader which allows you to
unread
characters. But there's the drawback:PushbackReader
does not provide areadLine
method.
回答2:
Consider of using something that is already made like OpenCSV. I think that you could create something like custom mapping strategy for it.
回答3:
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.
来源:https://stackoverflow.com/questions/9198280/java-bufferedreader-check-next-lines-of-a-loop-before-looping