我在Java中使用BufferedReader
来解析特定的文件格式。
文件看起来像这样:
HEADING_ONE
1
3
4.5
2
HEADING_TWO
2
6
etc...
所以,我使用以下代码来解析它:
BufferedReader br = new BufferedReader(reader);
String line = "";
while ((line = br.readLine()) != null) {
if (line.startsWith("HEADING_ONE")) {
while ((line = br.readLine()) != null) {
// Do something with the line, which is now a number
}
else if (line.startsWith("HEADING_TWO")) {
while... // The same as above
}
}
但是这段代码有一个问题 - 内部while循环吃下一行HEADING行。所以在第一次HEADING解析后,程序就会崩溃。
出于这个原因,我希望使用mark()
和reset()
。我修改了代码,以便内部 while循环看起来像:
while ((line = br.readLine()) != null) {
if (line.contains("HEADING")) {
br.reset();
break;
} else {
// Do something with the line, which is now a number.
}
br.mark(???)
}
这可以通过标记最后一行的位置来实现。如果解析器遇到新的标题行,则会将BufferedReader
备份到该位置。
但是,mark()
采用名为readAheadLimit
的参数
限制静止时可以读取的字符数 保留商标。尝试在读取后重置流 达到此限制或超出此限制的字符可能会失败。限制值更大 比输入缓冲区的大小会导致新的缓冲区 分配的大小不小于限制。因此价值很大 应小心使用。
在这种特殊情况下,有没有办法事先知道readAheadLimit
的大小?或者我计算最大标题的长度并将其用作值?或者我应该强制执行某种行限制?
答案 0 :(得分:2)
创建Scanner
类是为了解决这些问题。您重写的代码使用Scanner看起来像:
Scanner scanner = new Scanner(reader);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("HEADING_ONE")) {
while (scanner.hasNextInt()) {
int i = scanner.nextInt();
// do something with int
// skip to next line
scanner.nextLine();
}
} else if (line.startsWith("HEADING_TWO")) {
while... // The same as above
}
}