2

我有一些代码从 BufferedReader 读取行并从它读取的数据创建一个对象,然后将其发送出去进行处理。这一直持续到 BufferedReader.readLine() 返回 null (即到达文件末尾或套接字关闭等)

我认为围绕它创建一个实现的类可能很有用,Iterable<MyObject>因此可以使用

IObjectReader objectReader = new MyObjectReader(someBufferedReaderThatExists);

for (IObjectToProcess obj : objectReader) {
    processTheObject(obj);
}

因为这可以更容易地注入不同IObjectReader的对象,这些对象可能会创建返回不同类型的IObjectToProcess对象。

然而,棘手的一点是实现Iterable.hasNext()- 我如何判断是否BufferedReader.readLine()会返回null而不实际调用它?

(注意:BufferedReader.ready()不是答案:它只是告诉我读取是否会阻塞,而不是它是否会返回null

4

1 回答 1

11

不要尝试绕过BufferedReaderapi;使用它。在hasNext()中,让您的读者继续阅读下一行。如果成功,缓存该行并返回true。使用缓存的行(并清除缓存)而不是readLine()在您实际需要下一行时调用。

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();
        }
    }
}
于 2013-07-02T16:44:20.400 回答