加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 09:59:51 所属栏目:安全 来源:网络整理
导读:考虑到操作位于 scala.collection.Iterator之上,我很惊讶这会引发内存不足错误.各行的大小很小(1KB) Source.fromFile("largefile.txt").getLines.map(_.size).max 它似乎正在尝试将整个文件加载到内存中.不确定哪一步触发了这个.这对于这样的基本操作来说是
考虑到操作位于 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中.

解决方法

我愿意成为一个问题,就是你计算’线’的方式与getLines不同.从 API:

(getLines) Returns an iterator who returns lines (NOT including newline
character(s)). It will treat any of rn,r,or n as a line
separator (longest match) – if you need more refined behavior you can
subclass Source#LineIterator directly.

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

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,以及索引是违规行的内容.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读