来自文件的可重用流

时间:2015-04-05 15:22:31

标签: file scala io scala-collections scala-2.10

如何从Scala中的文件创建可重用的流?我有一个巨大的文件,我想多次使用它的内容,但我可能不需要完整地读取整个文件

我尝试过这样的事情,没有成功,

  // file iterator
  val f =  Source.fromFile("numberSeq.txt").getLines

  // construct stream from file iterator
  def numSeq: Stream[BigInt] = Stream.cons(BigInt(f.next()),numSeq)

  //test
  numSeq take 5 foreach println
  numSeq take 5 foreach println //the stream continues to print next file lines instead of going back to the first line

1 个答案:

答案 0 :(得分:2)

最简单的方法是在迭代器上使用toStream

scala> val f = List(1,2,3,4,5,6,7,8,9,10).toIterator.toStream
f: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> f take 5 foreach println
1
2
3
4
5

scala> f take 5 foreach println
1
2
3
4
5

在您的具体案例中,问题是由于numSeq使用的是def而不是val,因此您在每次def次调用时都拥有了全新的流。您仍然需要val进行递归定义,但不要忘记在使用前将其保存到scala> def numSeq: Stream[BigInt] = Stream.cons(BigInt(f.next()),numSeq) numSeq: Stream[BigInt] scala> val numSeq1 = numSeq numSeq1: Stream[BigInt] = Stream(1, ?) scala> numSeq1 take 5 foreach println 1 2 3 4 5 scala> numSeq1 take 5 foreach println 1 2 3 4 5

numSeq

错误使用示例(通知numSeq1而不是scala> numSeq take 5 foreach println 6 7 8 9 10 scala> numSeq take 5 foreach println java.util.NoSuchElementException: next on empty iterator at scala.collection.Iterator$$anon$2.next(Iterator.scala:39) at scala.collection.Iterator$$anon$2.next(Iterator.scala:37) at scala.collection.LinearSeqLike$$anon$1.next(LinearSeqLike.scala:59) at .numSeq(<console>:14) ... 33 elided ):

#::

顺便说一下,cons还有更可爱的import Stream._ def numSeq: Stream[BigInt] = BigInt(f.next()) #:: numSeq val numSeq1 = numSeq 语法:

val numSeq = { 
  def numSeq: Stream[BigInt] = BigInt(f.next()) #:: numSeq 
  numSeq
}

最后,封装更好的版本:

{{1}}