使用 Node.js 写出巨大的 json (4 Gb)

Jan*_*ekx 7 javascript json node.js

我有一个非常巨大的 json 对象(使用名为 espree 的 JavaScript 解析器创建,包含一个对象数组)。我想将其写入 .json 文件,但每次都会因内存分配问题而失败(我的堆大小为 22 Gb)。

据我了解,当数据未写入文件时缓冲区会过载。

如果我仅使用同步文件操作,输出将写入文件,但应用程序的运行时间会扩展。

我尝试过但失败的解决方案(尝试序列化整个对象,然后尝试序列化数组的项目):

  • JSON.stringify
  • JSON流
  • big-json (应该将对象序列化为流,但缓冲区仍然过载..)
  • 监视耗尽事件

这是当前的代码:

const bjson= require('big-json');

function save(result) {
    let outputStream = fs.createWriteStream(/*path*/);

    const stringifyStream = bjson.createStringifyStream({
        body: result
    });

    function write(d) {
        let result = outputStream.write(d);
        if (!result) {
            outputStream.once('drain', write);
        }
    }

    stringifyStream.on('data', function (chunk) {
        writeData(chunk);
    });

    stringifyStream.on('end', function () {
        outputStream.end();
    });
}

let results = [/*results as an array, containing lots of json objects*/];
for (let i = 0; i < results.length; i++){
    save(result[i]);
}
Run Code Online (Sandbox Code Playgroud)

Azw*_*waw 0

性能问题来自 JSON 转换为字符串。我有同样的问题,我通过使用 msgpack 格式存储数据解决了这个问题。

已解释here,我使用 npm 在我的项目中安装了 msgpack-lite :

npm install msgpack-lite
Run Code Online (Sandbox Code Playgroud)

我编写了用于存储 JSON 对象的代码:

npm install msgpack-lite
Run Code Online (Sandbox Code Playgroud)

用于读取我的文件并恢复我的对象。我不知道为什么它不适用于 Streams :

var fs = require("fs");
var msgpack = require("msgpack-lite");

var writeStream = fs.createWriteStream("file.msp");
var encodeStream = msgpack.createEncodeStream();
encodeStream.pipe(writeStream);

// send multiple objects to stream
encodeStream.write(myBigObject);

// call this once you're done writing to the stream.
encodeStream.end();
Run Code Online (Sandbox Code Playgroud)