2012-08-16 16 views
21

Próbowałem odczytać plik wiersz po wierszu i wyprowadzić go do innego pliku, używając pliku Node.js.Node.js odczytywanie i zapisywanie wierszy pliku

Mój problem polega na tym, że linie czasami są pomieszane ze względu na asynchroniczną naturę Node.js.

np mój plik wejściowy jest jak: linia 1 linia 2 linia 3

ale plik wynikowy może być tak: linii 1 linia 3 linii 2

Poniżej jest mój kod.

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) { 
      })}); 
    } 
); 

Wszelkie przemyślenia zostaną docenione, dzięki.

Odpowiedz

34

Jeśli jesteś zapisując kod synchroniczny, używaj tylko funkcji synchronicznych:

var fs = require("fs"); 

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

Asynchronous podejściu można napisać coś podobnego

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

To bezpieczne miksuj i asynkuj wersje funkcji fs, ale nadal musisz ustawić callback w odpowiedniej kolejności –

+4

@AndreySidorov Dla początkujących łatwiej jest nie mieszać kodu synchronicznego i asynchronicznego i wybrać pojedyncze podejście. Na przykład OP otwiera plik asynchronicznie (w ten sposób kolejność wywołań 'open' nie jest zachowywana), ale z jakiegoś powodu używa synchronicznej wersji' write'. – penartur

1

Dlaczego nie używacie node.js wtyczki do tego samego: https://github.com/pvorb/node-read-files

Montaż: npm zainstalować odczytu plików

Zastosowanie:

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

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

     console.log(data); 
    }); 
3

Przypuszczam chcesz wykonać kilka obliczeń i/lub przekształcenia w każdej linii. Jeśli nie, to jedna prosta kopia-liner (spójrz na createReadStream documentation)

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

Teraz próbujesz za każdym razem chcesz napisać wiersz, aby otworzyć plik, a tak, to kolejność jest tu nieprzewidywalna. bardziej poprawna wersja kodu:

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(); 

pewnie bym użyć jednego z „danym strumieniu wejściowym, powiadom mnie na każdej linii” moduły, na przykład node-lazy lub 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'); 
Powiązane problemy