简体   繁体   中英

Java: Multi-line File Read Iterator

I am trying to override the next() and nextLine() methods in the LineIterator class (org.apache.commons.io). Basically I want to specify the maximum number of lines to read from the text file for each invocation (default for the base class is of course 1).

Here is the derived class that I have come up with. Unfortunately it throws a StackOverflowError exception.

import java.io.File;
import java.io.FileReader;
import java.io.Reader;

import org.apache.commons.io.LineIterator;

public class MultiLineIterator extends LineIterator{
    int maxLines = 1;

    public static void main(String[] args) throws Exception {
        File file = new File ("/path/to/inputfile.txt");

        LineIterator iterator = new MultiLineIterator(new FileReader(file), 3);

        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }


    public MultiLineIterator(Reader reader, int maxLines) {
        super(reader);
        this.maxLines = maxLines;
    }

    @Override
    public String next() {
        String retVal = null;
        if(hasNext()) {
            retVal = "";
        }

        String nextFragment = "";
        for(int i = 1; i <= maxLines; i++) {
            if(hasNext()) {
                nextFragment = super.next();
                retVal += (nextFragment + " ");
            }
            else
                break;
        }
        return retVal;
    }


    @Override
    public String nextLine() {
        return next();
    }
}

To fix StackOverflowError you should remove:

@Override
public String nextLine() {
    return next();
}

, because you have an infinite recursion:

this:next() -> super:next() -> this:nextLine() -> this:next() -> ... and so on

Also I would suggest do not override next() method in this way it leads to inconsistent results. I would propose to use simple counter. Increment it on next line and check the counter on hasNext :

public class MultiLineIterator extends LineIterator {
    private int maxLines = 1;
    private int cursor = 0;

    public static void main(String[] args) throws Exception {
        File file = new File("/path/inputfile.txt");

        LineIterator iterator = new MultiLineIterator(new FileReader(file), 3);

        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    public MultiLineIterator(Reader reader, int maxLines) {
        super(reader);
        this.maxLines = maxLines;
    }

    @Override
    public boolean hasNext() {
        return (cursor < maxLines) && super.hasNext();
    }

    @Override
    public String next() {
        String next = super.next();
        cursor++;
        return next;
    }
}

In this implementation we do not concatenate lines but just limit the number.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM