当输入流管道到多输出流时,缓冲级别会发生什么?

问题描述 投票:3回答:1

我正在阅读流文档,并在https://nodejs.org/api/stream.html#stream_buffering上寻找有关流的缓冲行为描述

该文件似乎没有提到inputStream缓冲区(或缓冲区?)会发生什么,当管道到多个输出时,不同的输出具有不同的消耗速度:

在管道多个输出时,readableStream是否为每个输出保留专用缓冲区?

消费时输出是否保持相同的速度,或者更快的结束更早?

const input = fs.createReadStream('img.jpg');
const target1 = input.pipe(fs.createWriteStream('target1.jpg'));
const target2 = input.pipe(fs.createWriteStream('target2.jpg'));
javascript node.js stream buffer fs
1个回答
4
投票

TL; DR:简短的答案是 - 较慢的目标流控制流速。

首先让我们看看读取方面会发生什么。

const input = fs.createReadStream('img.jpg');

当您实例化输入流时,它将以暂停模式创建并安排读取(不会同步读取,因此它不会访问该文件)。该流的highWaterMark设置为类似于16384,目前有一个0字节的缓冲区。

const target1 = input.pipe(fs.createWriteStream('target1.jpg'));
const target2 = input.pipe(fs.createWriteStream('target2.jpg'));

现在,当您实际将其传输到可写流时,通过在on('data')中添加pipe method implementation - see the source事件处理程序来设置流动模式。

完成后我假设没有更多程序要运行,因此节点启动实际读取并在上面的处理程序中运行计划代码,该代码只是写入通过的任何数据。

当任何目标有更多的数据要写入时,流量控制就会发生,而highWaterMarkwrite操作返回false。然后由calling pause here in the code停止阅读。在此之上的两行你会看到state.awaitDrain增加了。

现在读取流再次是paused,可写流正在将字节写入磁盘 - 在某些时候缓冲级别再次低于highWaterMark。在这一点上,drain事件被解雇了executes this line,并且在所有等待的排水管被召唤之后,恢复流动。这是通过检查递减的awaitDrain属性是否已达到零来完成的,这意味着已经调用了所有等待的排出事件。

在上面的例子中,两个流中较快的一个可以在写入时返回一个假值,但它肯定会排在第一个。如果不是awaitDrain,则更快的流将恢复数据流,这将导致两者中较慢的缓冲区溢出。

© www.soinside.com 2019 - 2024. All rights reserved.