¿Leer un archivo una línea a la vez en node.js?
Estoy intentando leer un archivo grande, una línea a la vez. Encontré una pregunta en Quora que trataba sobre el tema, pero me faltan algunas conexiones para que todo encaje.
var Lazy=require("lazy");
new Lazy(process.stdin)
.lines
.forEach(
function(line) {
console.log(line.toString());
}
);
process.stdin.resume();
Lo que me gustaría descubrir es cómo puedo leer una línea a la vez de un archivo en lugar de STDIN como en este ejemplo.
Lo intenté:
fs.open('./VeryBigFile.csv', 'r', '0666', Process);
function Process(err, fd) {
if (err) throw err;
// DO lazy read
}
pero no funciona. Sé que en caso de apuro podría recurrir a algo como PHP, pero me gustaría resolver esto.
No creo que la otra respuesta funcione ya que el archivo es mucho más grande que la memoria que tiene el servidor en el que lo estoy ejecutando.
Desde Node.js v0.12 y a partir de Node.js v4.0.0, existe un módulo principal de línea de lectura estable. Esta es la forma más sencilla de leer líneas de un archivo, sin ningún módulo externo:
const fs = require('fs');
const readline = require('readline');
async function processLineByLine() {
const fileStream = fs.createReadStream('input.txt');
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
for await (const line of rl) {
// Each line in input.txt will be successively available here as `line`.
console.log(`Line from file: ${line}`);
}
}
processLineByLine();
O alternativamente:
var lineReader = require('readline').createInterface({
input: require('fs').createReadStream('file.in')
});
lineReader.on('line', function (line) {
console.log('Line from file:', line);
});
lineReader.on('close', function () {
console.log('all done, son');
});
La última línea se lee correctamente (a partir de Node v0.12 o posterior), incluso si no hay un archivo \n
.
ACTUALIZACIÓN : este ejemplo se ha agregado a la documentación oficial de la API de Node .
Para una operación tan sencilla no debería haber ninguna dependencia de módulos de terceros. Con calma.
var fs = require('fs'),
readline = require('readline');
var rd = readline.createInterface({
input: fs.createReadStream('/path/to/file'),
output: process.stdout,
console: false
});
rd.on('line', function(line) {
console.log(line);
});
rd.on('close', function() {
console.log('all done, son');
});
Actualización en 2019
Ya se ha publicado un ejemplo asombroso en la documentación oficial de Nodejs. aquí
Esto requiere que la última versión de Nodejs esté instalada en su máquina. >11.4
const fs = require('fs');
const readline = require('readline');
async function processLineByLine() {
const fileStream = fs.createReadStream('input.txt');
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
for await (const line of rl) {
// Each line in input.txt will be successively available here as `line`.
console.log(`Line from file: ${line}`);
}
}
processLineByLine();
No es necesario que acceda open
al archivo, sino que debe crear un archivo ReadStream
.
fs.createReadStream
Luego pasa esa corriente aLazy
require('fs').readFileSync('file.txt', 'utf-8').split(/\r?\n/).forEach(function(line){
console.log(line);
})