令人惊讶的scala Iterator“内存不足”错误

时间:2015-03-03 02:26:50

标签: scala

我很惊讶,考虑到操作位于scala.collection.Iterator之上,这会引发内存不足错误。各条线的尺寸很小(<1KB)

Source.fromFile("largefile.txt").getLines.map(_.size).max

它似乎正在尝试将整个文件加载到内存中。不确定哪一步触发了这个。这对于这样的基本操作来说是令人失望的行为。有一个简单的方法围绕它。图书馆实施者设计这个设计的原因是什么?

在Java8中尝试过相同的事情。

Files.lines(Paths.get("largefile.txt")).map( it -> it.length() ).max(Integer::max).get
//result: 3131

这可以预测。 Files.lines返回java.util.stream.Stream,堆不会爆炸。

更新:看起来它归结为新的线路解释。这两个文件都被解释为UTF-8,并且它们都调用java.io.BufferedReader.readLine()。所以,仍然需要弄清楚差异在哪里。我将两个片段主要类编译到同一个项目jar中。

1 个答案:

答案 0 :(得分:3)

我愿意成为一个问题,就是你计算'line'的方式与getLines不同。来自API:

  

(getLines)返回一个返回行的迭代器(不包括换行符   字符(S))。它会将\ r \ n,\ r \ n或\ n中的任何一个视为一行   分隔符(最长匹配) - 如果您需要更精细的行为   子类Source#LineIterator直接。

尝试针对相关文件执行此操作:

  Source.fromFile("testfile.txt").getLines().
    zipWithIndex.map{ case(s, i) => (s.length, i)}.
      foreach(e=> if (e._1 > 1000) println(
        "line: " + e._2 + " is: " + e._1 + " bytes!"))

这将告诉您文件中有多少行大于1K,以及索引是违规行的内容。

相关问题