2012-02-06 25 views
65

Necesito pasar un archivo de texto en el terminal y luego leer los datos del mismo, ¿cómo puedo hacer esto?¿Lees un archivo de texto usando Node.js?

node server.js file.txt 

¿Cómo paso en la ruta desde la terminal? ¿Cómo leo eso en el otro lado?

+0

Si usted se encuentra añadiendo más opciones en la línea de comandos, puede utilizar [Optimist] (https://github.com/substack/node-optimist) – Jess

+0

http://stackoverflow.com/questions/6156501/read-a-file-one-line-at-a-time-in-node-js?rq=1 muestra otra forma de leer un archivo de texto –

Respuesta

111

Querrá utilizar la matriz process.argv para acceder a los argumentos de la línea de comandos para obtener el nombre de archivo y FileSystem module (fs) para leer el archivo. Por ejemplo:

// Make sure we got a filename on the command line. 
if (process.argv.length < 3) { 
    console.log('Usage: node ' + process.argv[1] + ' FILENAME'); 
    process.exit(1); 
} 
// Read the file and print its contents. 
var fs = require('fs') 
    , filename = process.argv[2]; 
fs.readFile(filename, 'utf8', function(err, data) { 
    if (err) throw err; 
    console.log('OK: ' + filename); 
    console.log(data) 
}); 

romper ese abajo un poco para usted process.argv por lo general tienen longitud dos, siendo el intérprete de "nodo" y la primera el elemento cero siendo el guión que el nodo se está ejecutando actualmente, artículos después de que eran pasado en la línea de comando. Una vez que haya sacado un nombre de archivo de argv, puede usar las funciones del sistema de archivos para leer el archivo y hacer lo que quiera con su contenido. ejemplos de uso se vería así:

$ node ./cat.js file.txt 
OK: file.txt 
This is file.txt! 

[Editar] Como @wtfcoder menciona, utilizando el método de "fs.readFile()" podría no ser la mejor idea porque va a amortiguar todo el contenido del archivo antes de ceder a la función de devolución de llamada. Este almacenamiento en memoria intermedia podría potencialmente usar mucha memoria, pero, lo que es más importante, no aprovecha una de las funciones principales de node.js: E/S asincrónica y con evented.

La forma de "nodo" para procesar un archivo grande (o cualquier archivo, realmente) sería usar fs.read() y procesar cada porción disponible, ya que está disponible desde el sistema operativo. Sin embargo, leer el archivo como tal requiere que usted haga su propio (posible) análisis/procesamiento incremental del archivo y cierta cantidad de almacenamiento en memoria intermedia puede ser inevitable.

+0

Impresionante, gracias mucho, muy útil. ¿Cómo podría dividir estos datos por línea? – fancy

+5

@fancy: intente 'var lines = data.split (/ \ r? \ N /);', luego la matriz "lines" tendrá cada línea. – maerics

+0

bueno, sí, lo hice antes de volver, ¡gracias de nuevo! – fancy

20

En mi humilde opinión, fs.readFile() debe evitarse porque carga TODO el archivo en la memoria y no llamará a la devolución de llamada hasta que todo el archivo haya sido leído.

La manera más fácil de leer un archivo de texto es leerlo línea por línea. Yo recomiendo un BufferedReader:

new BufferedReader ("file", { encoding: "utf8" }) 
    .on ("error", function (error){ 
     console.log ("error: " + error); 
    }) 
    .on ("line", function (line){ 
     console.log ("line: " + line); 
    }) 
    .on ("end", function(){ 
     console.log ("EOF"); 
    }) 
    .read(); 

Para estructuras de datos complejas como .properties o archivos JSON es necesario utilizar un analizador (internamente sino que también debe utilizar un lector de buffer).

+6

Gracias por señalar esta técnica. Tienes razón de que esta puede ser la mejor manera, pero pensé que era un poco confuso en el contexto de esta pregunta, que creo que se trata de un caso de uso poco exigente. Como se señaló anteriormente, si solo se pasa un pequeño archivo a una herramienta de línea de comandos, no hay razón para no usar 'fs.readFile()' o 'fs.readFileSync()'. Tiene que ser un archivo enorme para causar una espera notable. Es probable que un archivo de configuración JSON como package.json sea menor de 1 kb, por lo que puede simplemente 'fs.readFile()' y 'JSON.parse()'. –

+0

BufferedReader puede haber cambiado su firma. Tuve que reemplazar BufferedReader con BufferedReader, DataReader, donde BufferedReader era el módulo. Ver https://github.com/Gagle/Node-BufferedReader – bnieland

+6

Veo que BufferedReader ahora está en desuso. –

1

Puede usar readstream y pipe para leer el archivo línea por línea sin leer todo el archivo en la memoria una sola vez.

var fs = require('fs'), 
    es = require('event-stream'), 
    os = require('os'); 

var s = fs.createReadStream(path) 
    .pipe(es.split()) 
    .pipe(es.mapSync(function(line) { 
     //pause the readstream 
     s.pause(); 
     console.log("line:", line); 
     s.resume(); 
    }) 
    .on('error', function(err) { 
     console.log('Error:', err); 
    }) 
    .on('end', function() { 
     console.log('Finish reading.'); 
    }) 
); 
1

Estoy publicando un ejemplo completo que finalmente funcionó. Aquí estoy leyendo en un archivo rooms/rooms.txt de un guión rooms/rooms.js

var fs = require('fs'); 
var path = require('path'); 
var readStream = fs.createReadStream(path.join(__dirname, '../rooms') + '/rooms.txt', 'utf8'); 
let data = '' 
readStream.on('data', function(chunk) { 
    data += chunk; 
}).on('end', function() { 
    console.log(data); 
}); 
Cuestiones relacionadas