我有一些代码从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
)
答案 0 :(得分:10)
不要尝试解决BufferedReader
api;与它合作。在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();
}
}
}