Pregunta

I am using a BufferedReader in Java to parse a specific file format.

The files look something like this:

HEADING_ONE
1
3
4.5
2
HEADING_TWO
2
6
etc...

So, I am using the following code to parse this:

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

But this code has an issue with it - the inner while loops eat the next line HEADING line. So after the first HEADING parse, the program breaks down.

It is for this reason that I wish to use mark() and reset(). I modified the code so that the inner while loop looks something like:

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(???)
}

This works by marking the location of the last line. If the parser encounters a new heading line, it backs up the BufferedReader to that location.

However, mark() takes an argument called readAheadLimit which is a

Limit on the number of characters that may be read while still preserving the mark. An attempt to reset the stream after reading characters up to this limit or beyond may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.

Is there any way to know in advance the size of the readAheadLimit in this particular case? Or do I calculate the length of the largest heading and use that as a value? Or should I enforce some sort of line limit?

¿Fue útil?

Solución

The Scanner class was created to solve these kinds of problems. Your code rewritten to use Scanner would look like:

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
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top