如何尽可能小的占用内存,从大JSON文件中取数据?
发布于 10 年前 作者 sjfkai 16519 次浏览 最后一次编辑是 8 年前 来自 问答

当我需要从一个json文件中区数据时,最先想到的方法就是:

fs.readFile('./data.json', function (err, data) {
  if (err) throw err;
  var data = JSON.parse(data);
  cb(data.aaa);
});

简单说就是把整个文件读取到内存中,再把json转换为js对象,再去取相应数据。

可是,当json文件很大时,上面一段逻辑占用内存实在太大了。有没有比较好的省内存的方法可以完成以上操作呢?

9 回复

用流控制一下可能会好点吧

用这个库试试? https://github.com/dominictarr/JSONStream 我不确定用流能不能把内存占用降下来。

流也没用把,你json的 不全部读完,没法JSON.parse。。。

的确没想到啥好办法,不过既然楼主这么关注内存和就操作结果而论的话,为何不试试将数据存入数据库中,衡量一下是否愿意用网络IO开销来换文件IO开销和宝贵的内存开销?毕竟这样的话,就结果而论,关注的在内存中的量,只是微乎其微的楼主想要的那条数据了。(话说有robomogo这等工具将json格式数据存入mongodb就是复制黏贴的事儿。。。)

用流并及时消费掉流。如果只是用read,那么内存没被消费完可能就因下次read(比如并发)而增加内存。

如果偏要读取文件的方式做输入,试试换个文件格式,比如按行记录 只要文件能拆成小块后依然能解析,就可以分块处理了 可以考虑readline

不过一个node变量占用十几兆内存不算事儿,只要不频繁操作它。如果是几百兆的log文件,就真得考虑分块处理了。

感谢各位的回答,问题出现在我的DigitalOcean服务器仅剩200M内存时,去跑grab12306 跑到一半因为内存占用过大系统就把进程Kill掉了。项目开发时没有过分考虑内存占用的问题,现在正好当做一个学习的机会来解决一下这个问题。 也请各位大神有空帮忙看看代码有没有可以优化的地方。

@sjfkai 我遇到过类似问题,解决方案是用流读入,因为文件结构已知(array of shallow JSON objects),所以可以判断JSON object的开始和结束。处理完的JSON object 字符串可以处理掉。这样可以用小内存处理很大的JSON文件。

回到顶部