Node.js流和数据消失

时间:2014-07-27 00:07:22

标签: javascript node.js

我一直在玩可读和变换流,我无法解开消失的线条之谜。

考虑一个文本文件,其中的行包含序号,从1到20000:

$ seq 1 20000 > file.txt

我创建了一个Readable流和一个LineStream(来自名为 byline 的库:npm install byline;我正在使用版本4.1.1):< / p>

var file = (require('fs')).createReadStream('file.txt');
var lines = new (require('byline').LineStream)();

请考虑以下代码:

setTimeout(function() {
  lines.on('readable', function() {
    var line;
    while (null !== (line = lines.read())) {
      console.log(line);
    } 
  });
}, 1500);

setTimeout(function() {
  file.on('readable', function() {
    var chunk;
    while (null !== (chunk = file.read())) {
      lines.write(chunk);
    }
  }); 
}, 1000);

请注意,它首先将一个侦听器附加到'readable'可读流的file事件,该事件写入lines流,并且仅在半秒后它附加一个侦听器'readable'流的lines事件,只是将行打印到控制台。

如果我运行此代码,它将只打印16384(即2 ^ 14)行并停止。它不会完成该文件。但是,如果我将1500ms超时更改为500ms - 有效地交换了连接侦听器的顺序,它将很乐意打印整个文件。

我尝试过使用highWaterMark,指定从文件流中读取的字节数,将侦听器附加到行流的其他事件,都是徒劳的。

什么可以解释这种行为?

谢谢!

1 个答案:

答案 0 :(得分:2)

我认为这种行为可以解释为两件事:

  1. 如何使用流。
  2. byline如何运作。
  3. 您所做的是手动管道。它的问题在于它不尊重highWaterMark并强制整体被缓冲。

    所有这些都会导致byline表现不佳。见:https://github.com/jahewson/node-byline/blob/master/lib/byline.js#L110-L112。这意味着当缓冲区长度> 1时,它停止推线。 highWaterMark。但这没有任何意义!它不会阻止内存使用量的增长(行仍然存储在特殊的行缓冲区中),但是流不知道这些行,如果它以溢出状态结束,它们将永远丢失。

    你能做什么:

    1. 使用pipe
    2. 修改highWaterMarklines._readableState.highWaterMark = Infinity;
    3. 停止使用byline