2012-08-16 20 views
21

Intenté leer un archivo línea por línea y enviarlo a otro archivo, usando Node.js.Node.js líneas de archivo de lectura y escritura

Mi problema es la secuencia de líneas a veces en mal estado debido a la naturaleza asincrónica de Node.js.

por ejemplo, mi archivo de entrada es como: línea 1 línea 2 línea de archivo de salida 3

pero podría ser como: línea 1 línea 3 línea 2

A continuación se muestra el código.

var fs = require("fs"); 
var index = 1; 

fs.readFileSync('./input.txt').toString().split('\n').forEach(
function (line) { 
    console.log(line); 
     fs.open("./output.txt", 'a', 0666, function(err, fd) { 
      fs.writeSync(fd, line.toString() + "\n", null, undefined, function(err, written) { 
      })}); 
    } 
); 

Cualquier pensamiento sería apreciado, gracias.

Respuesta

34

Si eres escribiendo un código síncrono, use solo las funciones síncronas:

var fs = require("fs"); 

fs.readFileSync('./input.txt').toString().split('\n').forEach(function (line) { 
    console.log(line); 
    fs.appendFileSync("./output.txt", line.toString() + "\n"); 
}); 

Para enfoque asíncrono se podría escribir algo así como

var fs = require('fs'), 
    async = require('async'), 
    carrier = require('carrier'); 

async.parallel({ 
    input: fs.openFile.bind(null, './input.txt', 'r'), 
    output: fs.openFile.bind(null, './output.txt', 'a') 
}, function (err, result) { 
    if (err) { 
     console.log("An error occured: " + err); 
     return; 
    } 

    carrier.carry(result.input) 
     .on('line', result.output.write) 
     .on('end', function() { 
      result.output.end(); 
      console.log("Done"); 
     }); 
}); 
+1

que es seguro mezcla las versiones sincronizadas y asíncronas de las funciones fs, pero aún tienes que establecer las devoluciones de llamadas en el orden correcto –

+4

@AndreySidorov Para un principiante es más fácil no mezclar el código síncrono y asíncrono y elegir un solo enfoque. Por ejemplo, OP abre el archivo de forma asincrónica (para que el orden de las llamadas a 'abrir' no se conserve), pero luego, por algún motivo, utiliza la versión síncrona de' write'. – penartur

1

¿Por qué no usar Node.js plug-in para el mismo: https://github.com/pvorb/node-read-files

Instalación: NPM instalar leer archivos

Uso:

var fs = require("fs"); 
     require("read-files"); 

    fs.readFiles([ "file1", "file2" ], "utf8", function(err, data) { 
     if (err) throw err; 

     console.log(data); 
    }); 
3

supongo que desea realizar algunos cálculos y/o transformaciones en cada línea. Si no es así, copia simple es de una sola línea (echar un vistazo a createReadStream documentation)

fs.createReadStream('./input.txt').pipe(fs.createWriteStream('./output.txt')); 

Ahora, usted está tratando de abrir el archivo cada vez que se desea escribir la línea, y sí, el orden es impredecible aquí. versión más correcta de su código:

var lines = fs.readFileSync('./input.txt').toString().split('\n') 
function writeLineFromArray(lines) { 
    var line = arr.shift(); 
    fs.open("./output.txt", 'a', 0666, function(err, fd) { 
     fs.writeSync(fd, line + '\n', null, undefined, function(err, written) { 
      writeLineFromArray(lines); 
     }); 
    }); 
} 
writeLinesFromArray(); 

probablemente haría uso de uno de 'flujo de entrada dada, notifiqúeme en cada línea' módulos, por ejemplo node-lazy o byline:

var fs = require('fs'), 
    byline = require('byline'); 

var stream = byline(fs.createReadStream('sample.txt')); 
stream.on('line', function(line) { 
    // do stuff with line 
}); 
stream.pipe(fs.createWriteStream('./output'); 
Cuestiones relacionadas