我很惊讶,考虑到操作位于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中。
答案 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,以及索引是违规行的内容。