正如标题所暗示的,我正试图在我的Node.js应用程序中使用JSON.stringify
将巨大的JavaScript对象串化。这些对象又是巨大的(数十兆字节),它们不包含任何函数。我需要将序列化的对象写入一个文件。我现在得到的是:
RangeError: Invalid string length
at Object.stringify (native)
at stringifyResult (/my/file.js:123:45) -> line where I use JSON.stringify
你知道怎么解决这个问题吗?
发布于 2015-03-27 04:05:38
我也看到了这个无用的/误导性的nodejs错误消息,所以我在nodejs github上预订了一个问题
RangeError: Invalid string length --- it should be saying Out Of Memory
发布于 2021-10-13 02:01:17
正如@sandeepanu所提到的,如果你想把一个巨大的数组串起来,there's a great little solution by @madhunimmo。一次只对一个元素进行字符串化:
let out = "[" + yourArray.map(el => JSON.stringify(el)).join(",") + "]";
如果你想让一个对象具有大量的键/属性,那么你可以先对它使用Object.entries()
,把它变成一个键/值对的数组:
let out = "[" + Object.entries(yourObject).map(el => JSON.stringify(el)).join(",") + "]";
如果这仍然不起作用,那么您可能希望使用流方法,尽管您可以将数组分成多个部分并存储为多个jsonl
(每行一个对象)文件:
// untested code
let numFiles = 4;
for(let i = 0; i < numFiles; i++) {
let out = arr.slice((i/numFiles)*arr.length, ((i+1)/numFiles)*arr.length).map(el => JSON.stringify(el)).join(",");
// add your code to store/save `out` here
}
一种流媒体方法(新的,目前只支持Chrome,但很可能会出现在其他浏览器上,甚至Deno和Node.js以这样或那样的形式)是使用File System Access API。代码将如下所示:
// untested code
const dirHandle = await window.showDirectoryPicker();
const fileHandle = await dirHandle.getFileHandle('yourData.jsonl', { create: true });
const writable = await fileHandle.createWritable();
for(let el of yourArray) {
await writable.write(JSON.stringify(el)+"\n");
}
await writable.close();
发布于 2021-12-02 23:04:21
我发现JSONStream是原生JSON.stringify的可靠替代品,它可以很好地处理大型对象。例如:
var fileSystem = require( "fs" );
var JSONStream = require( "JSONStream" );
var records = [
{ id: 1, name: "Terminator" },
{ id: 2, name: "Predator" },
{ id: 3, name: "True Lies" },
{ id: 4, name: "Running Man" },
{ id: 5, name: "Twins" }
// .... hundreds of thousands of records ....
];
var transformStream = JSONStream.stringify();
var outputStream = fileSystem.createWriteStream( __dirname + "/data.json" );
transformStream.pipe( outputStream );
records.forEach( transformStream.write );
transformStream.end();
outputStream.on(
"finish",
function handleFinish() {
console.log("Done");
}
);
取自here的示例代码。
https://stackoverflow.com/questions/29175877
复制相似问题