我正在解析.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.
}
答案 0 :(得分:8)
您可以使用BufferedReader.mark(int)
标记当前位置。要返回到您致电BufferedReader.reset()
的位置。 mark
的参数是“预读限制”;如果在读取超过限制后尝试reset()
,则可能会出现IOException。
或者您可以改为使用RandomAccessFile
:
// Get current position
long pos = raf.getFilePointer();
// read more lines...
// Return to old position
raf.seek(pos);
或者您可以使用允许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设置为新读取的值并继续外部循环。