2012-08-16 22 views
21

ファイルを1行ずつ読み込み、Node.jsを使って別のファイルに出力しようとしました。Node.jsファイル行を読み書きする

私の問題は、Node.jsの非同期性のために時々混乱してしまうことです。

例えば、私の入力ファイルのようである:1 ライン2 ライン3

が、出力ファイルは可能性があり 行のような:以下は2

ライン1 ライン3 ラインは私のコードです。

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

ご迷惑をおかけして申し上げます。

答えて

34

あなたがしている場合: NPM読み取りファイル

使い方をインストール同期コードを記述する場合は、同期関数のみを使用してください。

var fs = require("fs"); 

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

非同期的なアプローチのためにあなたが

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

それはしても安全ですfs関数の同期と非同期のバージョンがありますが、正しい順序でコールバックを設定する必要があります –

+4

@AndreySidorov初心者にとっては、同期コードと非同期コードを混ぜたり、単一の方法を選択したりする方が簡単です。例えば、OPはファイルを非同期的に開きます( 'open'への呼び出しの順序は保持されません)。何らかの理由で' write'の同期バージョンを使用します。 – penartur

1

は、なぜあなたは同じのためのプラグインのNode.js使用しないでください。https://github.com/pvorb/node-read-files

インストール:

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

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

     console.log(data); 
    }); 
3

ような何かを書くことができ、私はあなたがすべての行にいくつかの計算および/または変換を実行するとします。ない場合は、単純なコピーはワンライナー(createReadStream documentationを見てみましょう)

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

さて、あなたはファイルにあなたが行を書きたいたびに開こうとしているし、はい、順序はここに予測不可能です。あなたのコードの より正しいバージョン:

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

私はおそらく「指定された入力ストリームの各ライン上で私に通知」のいずれかを使用する例node-lazyまたは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'); 
関連する問題