Is it possible to know if BufferedReader.readLine() will return null in advance?

java

Solution

Don't try working around the `BufferedReader` api; work with it. In `hasNext()`, have your reader go ahead and try to read the next line. If it succeeds, cache the line and return `true`. Use the cached line (and clear the cache) instead of calling `readLine()` when you actually need the next line.

public class MyObjectReader implements Iterable<String> {
    private BufferedReader rdr;

    public MyObjectReader(BufferedReader rdr) {
        this.rdr = rdr;
    }

    @Override
    Iterator<String> iterator() {
        return new BufferedReaderIterator();
    }
    . . .

    private class BufferedReaderIterator implements Iterator<String> {
        String cachedLine;

        @Override
        public String next() {
            String result = cachedLine == null ? rdr.readLine() : cachedLine;
            cachedLine = null;
            if (result == null) {
                throw new NoSuchElementException();
            }
            return result;
        }

        @Override
        public boolean hasNext() {
            if (cachedLine == null) {
                cachedLine = rdr.readLine();
            }
            return cachedLine != null;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

Problem

I have some code that reads lines from a BufferedReader and creates an object from the data that it reads, then sends this off for processing. This continues until BufferedReader.readLine() returns null (i.e. end of file is reached or socket is closed, etc.) I thought it might be useful to create a class around this which implements `Iterable<MyObject>` so it could be consumed using ``` IObjectReader objectReader = new MyObjectReader(someBufferedReaderThatExists); for (IObjectToProcess obj : objectReader) { processTheObject(obj); } ``` as this could make it easier to inject different `IObjectReader` objects which might create return different types of `IObjectToProcess` objects. however the tricky bit is implementing `Iterable.hasNext()` - how can I tell if `BufferedReader.readLine()` will return `null` without actually calling it? (Note: `BufferedReader.ready()` is not the answer: it just tells me if a read will block, not if it will return `null`)

Original source