0

バックグラウンド -

node.js と fs モジュールを使用して、ファイルを監視し、ファイルに追加された行を検出するという最終目標を達成しようとしています。

現在の実装 -

私は現在、fs.watchを使用してファイルへの変更を永続的に監視し、fs.readFileを使用して監視がトリガーされたらファイルを読み取ります。

欠点 -

この実装の欠点は、特に、追加された行のみに関心があるにもかかわらず、ファイルの内容全体を読み取る必要があるため、この方法で追加された行を導出するのは計算コストが高く、時間がかかることです。

理想的なソリューション -

代わりにfs.createReadStreamを使用して、ファイルを最後まで読み取り、最後にファイル記述子を残し、ファイルが追加されたら再度読み取りを開始したいと思います。

ストリーム バッファの内容を読み取る 2 つの方法を見つけましたが、どちらの実装でもreadable.read()readable.on('data',...)が存在すると、ストリームは終了したようです。ストリームは閉じられていませんが、読み取るデータはもうありません。readable.resume()は何もしないように見えるため、終了したストリームを引き続き使用する方法が正確にはわかりません。

私の質問 -

ファイルが変更されるとトリガーされる方法で、ファイルから追加された行を読み取るにはどうすればよいですか? 私の理想的なソリューションは正しい方向に進んでいますか?

お時間をいただき、ありがとうございました。

4

1 に答える 1

1

これは私がかつて抱えていた問題であり、かなりの頭痛の種でした。これは私が思いついた実装です。

var fs = require('fs');

var file = __dirname + '/file.log';
fs.stat(file, function(err, stats) {
  var start = stats.size;
  // read the entire file here if you need it
  watchFile(start);
});

function watchFile(start) {
  fs.watch(file, function(event, filename) {
    fs.stat(file, function(err, stats) {
      var stream = fs.createReadStream(file, {
        start: start,
        end: stats.size
      });

      var lines = new String();
      stream.on('data', function(data) {
        lines += data;
      });

      stream.on('end', function() {
        // you have the new lines
      });

      start = stats.size + 1;
    });
  });
};

まず、ファイルのサイズを見つけて、ウォッチ関数に渡します。ファイルが変更されるたびに、ファイルの新しいサイズを見つけて、古い位置から新しい位置まで読み取ります。一部のシステムでは、watch 関数が変更ごとに 2 回起動することがあるため、チェックを追加して、開始と終了が同じバイトである場合などの無駄な読み取りを取り除くことができます。

于 2013-09-13T00:23:27.907 に答える