我一直在玩可读和变换流,我无法解开消失的线条之谜。
考虑一个文本文件,其中的行包含序号,从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,指定从文件流中读取的字节数,将侦听器附加到行流的其他事件,都是徒劳的。
什么可以解释这种行为?
谢谢!
答案 0 :(得分:2)
我认为这种行为可以解释为两件事:
byline
如何运作。您所做的是手动管道。它的问题在于它不尊重highWaterMark
并强制整体被缓冲。
所有这些都会导致byline
表现不佳。见:https://github.com/jahewson/node-byline/blob/master/lib/byline.js#L110-L112。这意味着当缓冲区长度> 1时,它停止推线。 highWaterMark。但这没有任何意义!它不会阻止内存使用量的增长(行仍然存储在特殊的行缓冲区中),但是流不知道这些行,如果它以溢出状态结束,它们将永远丢失。
你能做什么:
pipe
highWaterMark
:lines._readableState.highWaterMark = Infinity;
byline