【发布时间】:2010-10-24 20:27:14
【问题描述】:
我有一个迭代器(实际上是 Source.getLines),它从 URL 读取无限的数据流。当出现连接问题时,迭代器偶尔会抛出java.io.IOException。在这种情况下,我需要重新连接并重新启动迭代器。我希望这是无缝的,这样迭代器对消费者来说就像一个普通的迭代器,但在必要时会在下面重新启动。
例如,我希望看到以下行为:
scala> val iter = restartingIterator(() => new Iterator[Int]{
var i = -1
def hasNext = {
if (this.i < 3) {
true
} else {
throw new IOException
}
}
def next = {
this.i += 1
i
}
})
res0: ...
scala> iter.take(6).toList
res1: List[Int] = List(0, 1, 2, 3, 0, 1)
我对这个问题有部分解决方案,但它会在某些极端情况下失败(例如,重新启动后第一个项目上的 IOException)并且非常难看:
def restartingIterator[T](getIter: () => Iterator[T]) = new Iterator[T] {
var iter = getIter()
def hasNext = {
try {
iter.hasNext
} catch {
case e: IOException => {
this.iter = getIter()
iter.hasNext
}
}
}
def next = {
try {
iter.next
} catch {
case e: IOException => {
this.iter = getIter()
iter.next
}
}
}
}
我一直觉得有更好的解决方案,可能是 Iterator.continually 和 util.control.Exception 的某种组合或类似的东西,但我想不出一个。有什么想法吗?
【问题讨论】:
-
我在原始答案中添加了带有
continually和util.control.Exception的解决方案。
标签: exception scala iterator restart