当行添加到文件中时,如何使用单个文件描述符或流来检测和读取它们?

时间:2013-09-12 22:54:02

标签: javascript node.js file-descriptor node.js-stream

背景 -

我正在尝试使用node.js和fs模块来实现监视文件的最终目标,并检测已附加到其中的行。

当前实施 -

我目前正在使用fs.watch来持续监控文件的更改,并fs.readFile在手表触发后读取文件。

缺点 -

这种实现的缺点是计算成本高,并且以这种方式导出附加行很慢,特别是因为它需要读取整个文件内容,尽管我只对附加的行感兴趣。

理想解决方案 -

我想使用fs.createReadStream以某种方式读取文件直到结束,将文件描述符保留在最后,并在文件被追加后再次开始读取。

我找到了两种方法来读取流缓冲区的内容,但是在readable.read()readable.on('data',...)的两种实现中,一旦没有更多的数据,流就会结束读取,虽然流未关闭。我不确定如何继续使用已结束的流,因为readable.resume()似乎没有做任何事情。

我的问题 -

如何以修改文件后触发的方式从文件中读取附加行?我的理想解决方案是否正确?

感谢您的时间和帮助!

1 个答案:

答案 0 :(得分: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函数。每次文件更改时,我都会找到文件的新大小,并从旧位置读取到新位置。在某些系统上,监视功能可能会在每次更改时触发两次,因此您可能需要添加检查以消除无用的读取,例如当开始和结束是相同的字节时。