Como el título lo indica, estoy tratando de encadenar un objeto JavaScript enorme con JSON.stringify en mi aplicación Node.js. Los objetos son, de nuevo, enormes (decenas de megabytes), no contienen ninguna función. Necesito escribir los objetos serializados en un archivo. Lo que obtengo ahora es esto:
RangeError: Invalid string length at Object.stringify (native) at stringifyResult (/my/file.js:123:45) -> line where I use JSON.stringify¿Alguna idea de cómo resolver ese problema?
Yo también he visto este mensaje de error de nodejs inútil/engañoso, así que reservé un problema en nodejs github
RangeError: longitud de cadena no válida --- debería decir Sin memoria
Como mencionó @sandeepanu, hay una pequeña solución excelente de @madhunimmo si está tratando de encadenar una gran variedad. Simplemente encadene un elemento a la vez:
let out = "[" + yourArray.map(el => JSON.stringify(el)).join(",") + "]"; Si está tratando de clasificar un objeto con una gran cantidad de claves/propiedades, entonces podría usar Object.entries() primero para convertirlo en una matriz de pares clave/valor primero:
let out = "[" + Object.entries(yourObject).map(el => JSON.stringify(el)).join(",") + "]"; Si eso aún no funciona, entonces probablemente desee utilizar un enfoque de transmisión, aunque podría dividir su matriz en porciones y almacenarla como varios jsonl (un objeto por línea):
// 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 }Un enfoque de transmisión (nuevo, y actualmente solo compatible con Chrome, pero probablemente llegará a otros navegadores, e incluso a Deno y Node.js de una forma u otra) es usar la API de acceso al sistema de archivos . El código sería algo como esto:
// 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();Considero que JSONStream es una alternativa confiable al JSON.stringify nativo que funciona bien con objetos grandes. Por ejemplo:
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"); } );Tomó el código de muestra de aquí .