Necesito generar una gran cantidad de combinaciones de valores de cadena, unos pocos miles de millones de líneas y escribirlas todas en un archivo grande en el disco sin que se bloquee el proceso.
En este momento funciona hasta que se llena el búfer de escritura del archivo, para pequeñas listas de palabras, cuando intento con una mayor cantidad de registros, los archivos de salida quedan vacíos.
const fs = require('fs'); const words = fs.readFileSync('./1024words.txt').toString().split("\n"); //create array of 1024 words let fileout , row = '' , wordA, wordB, wordC , totRows = Math.pow(words.length,3)*3 //combination of 3 words for 3 columns of output , count = 0; for (let indexA = 0; indexA < words.length; indexA++) { wordA = words[ indexA ]; fileout = fs.createWriteStream(`${wordA}.csv`); //new output file for (let indexB = 0; indexB < words.length; indexB++) { wordB = words[ indexB ]; for (let indexC = 0; indexC < words.length; indexC++) { wordC = words[ indexC ]; row = `${wordA} ${wordB} ${wordC}\n`; count++; process.stdout.write(`${count} of ${totRows} written: ${row}`); fileout.write(row); } } fileout.end(); fileout.close(); }te falta un manejo de contrapresión
más lecturas aquí
https://nodejs.org/en/docs/guides/backpressuring-in-streams/
añadir esta función
function writeToStream(stream, data) { const canContinue = stream.write(data); if (!canContinue) { stream.pause() stream.once('drain', () => { stream.resume() }) } }código completo:
const fs = require('fs'); const words = fs.readFileSync('./1024words.txt').toString().split("\n"); //create array of 1024 words let fileout , row = '' , wordA, wordB, wordC , totRows = Math.pow(words.length, 3) * 3 //combination of 3 words for 3 columns of output , count = 0; for (let indexA = 0; indexA < words.length; indexA++) { wordA = words[indexA]; fileout = fs.createWriteStream(`${wordA}.csv`); //new output file for (let indexB = 0; indexB < words.length; indexB++) { wordB = words[indexB]; for (let indexC = 0; indexC < words.length; indexC++) { wordC = words[indexC]; row = `${wordA} ${wordB} ${wordC}\n`; count++; writeToStream(process.stdout, `${count} of ${totRows} written: ${row}`) writeToStream(fileout, row) } } fileout.end(); fileout.close(); } function writeToStream(stream, data) { const canContinue = stream.write(data); if (!canContinue) { stream.pause() stream.once('drain', () => { stream.resume() }) } }