我在玩Scala的懶惰迭代器,並且遇到了一個問題。我正在試圖做的是在一個大文件讀取,做一個轉換,然後寫出來的結果是:Scala無限迭代器OutOfMemory
object FileProcessor {
def main(args: Array[String]) {
val inSource = Source.fromFile("in.txt")
val outSource = new PrintWriter("out.txt")
try {
// this "basic" lazy iterator works fine
// val iterator = inSource.getLines
// ...but this one, which incorporates my process method,
// throws OutOfMemoryExceptions
val iterator = process(inSource.getLines.toSeq).iterator
while(iterator.hasNext) outSource.println(iterator.next)
} finally {
inSource.close()
outSource.close()
}
}
// processing in this case just means upper-cases every line
private def process(contents: Seq[String]) = contents.map(_.toUpperCase)
}
所以我得到的大量文件一個OutOfMemoryException。我知道如果你圍繞着Stream的頭部引用,你可能會和Scala的懶惰Streams發生衝突。所以在這種情況下,我會小心地將process()的結果轉換爲迭代器,並丟棄最初返回的Seq。
有誰知道爲什麼這仍然會導致O(n)內存消耗?謝謝!
更新
針對FGE和huynhjl,就好像序列可能是罪魁禍首,但我不知道爲什麼。作爲一個例子,下面的代碼工作正常(我在各地使用Seq)。此代碼不產生一個OutOfMemoryException:
object FileReader {
def main(args: Array[String]) {
val inSource = Source.fromFile("in.txt")
val outSource = new PrintWriter("out.txt")
try {
writeToFile(outSource, process(inSource.getLines.toSeq))
} finally {
inSource.close()
outSource.close()
}
}
@scala.annotation.tailrec
private def writeToFile(outSource: PrintWriter, contents: Seq[String]) {
if (! contents.isEmpty) {
outSource.println(contents.head)
writeToFile(outSource, contents.tail)
}
}
private def process(contents: Seq[String]) = contents.map(_.toUpperCase)
狂猜:'.getLines.toSeq'? – fge 2011-12-27 02:28:15