当我需要从一个json
文件中区数据时,最先想到的方法就是:
fs.readFile('./data.json', function (err, data) {
if (err) throw err;
var data = JSON.parse(data);
cb(data.aaa);
});
简单说就是把整个文件读取到内存中,再把json转换为js对象,再去取相应数据。
可是,当json文件很大时,上面一段逻辑占用内存实在太大了。有没有比较好的省内存的方法可以完成以上操作呢?
用流控制一下可能会好点吧
用这个库试试? 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文件。