Node.jsstream和数据消失
我一直在玩可读和变形的stream,我无法解决消失的线条的奥秘。
考虑一个文本文件,其中的行包含连续的数字,从1到20000:
$ seq 1 20000 > file.txt
我创build了一个Readable
stream和一个LineStream
(从一个名为LineStream
的库: npm install byline
LineStream
;我使用的是版本4.1.1):
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);
注意,它首先将一个监听器附加到file
Readablestream的'readable'
事件上,该file
写入lines
stream,只有半秒钟后,它将一个监听器附加到lines
stream的'readable'
事件上,线到控制台。
如果我运行这个代码,它将只打印16384(这是2 ^ 14)线,并停止。 它不会完成文件。 但是,如果我将1500毫秒超时更改为500毫秒 – 有效地交换侦听器的连接顺序,它将愉快地打印整个文件。
我试着玩highWaterMark,指定从文件stream中读取的字节数量,将听众附加到行stream的其他事件上,都是徒劳的。
什么可以解释这种行为?
谢谢!
我认为这个行为可以用两件事来解释:
- 你如何使用stream。
- 如何通过运作。
你所做的是手动pipe道。 问题在于它不尊重highWaterMark
并强制整体被缓冲。
所有这些都会导致byline
行为不佳。 看到这个: https : //github.com/jahewson/node-byline/blob/master/lib/byline.js#L110-L112 。 这意味着当缓冲区长度> highWaterMark时,它会停止按下行。 但这没有任何意义! 它不会阻止内存使用量的增长(线路仍然存储在特殊的线路缓冲区中),但是stream不知道这些线路,如果以溢出状态结束,它们将永远丢失。
你可以做什么:
- 使用
pipe
- 修改
highWaterMark
:lines._readableState.highWaterMark = Infinity;
- 停止使用
byline