【问题标题】:How to read from one stream and write to several at once?如何从一个流中读取并一次写入多个流?
【发布时间】:2017-08-27 12:22:34
【问题描述】:

假设我有一个readable 流,例如request(URL)。我想通过fs.createWriteStream() 将它的响应写在磁盘上,并通过管道发送请求。但同时我想通过crypto.createHash()流计算下载数据的校验和。

readable -+-> calc checksum
          |
          +-> write to disk

而且我想在运行中完成它,而不是在内存中缓冲整个响应。

看来我可以使用 oldschool on('data') 钩子来实现它。伪代码如下:

const hashStream = crypto.createHash('sha256');
hashStream.on('error', cleanup);

const dst = fs.createWriteStream('...');
dst.on('error', cleanup);

request(...).on('data', (chunk) => {
    hashStream.write(chunk);
    dst.write(chunk);
}).on('end', () => {
    hashStream.end();
    const checksum = hashStream.read();
    if (checksum != '...') {
        cleanup();
    } else {
        dst.end();
    }
}).on('error', cleanup);

function cleanup() { /* cancel streams, erase file */ };

但是这种方法看起来很尴尬。我尝试使用stream.Transformstream.Writable 来实现read | calc + echo | write 之类的东西,但我坚持执行。

【问题讨论】:

    标签: javascript node.js pipeline node-streams


    【解决方案1】:

    Node.js 可读流有一个 .pipe 方法,它的工作方式与 unix 管道运算符非常相似,除了您可以流式传输 js 对象以及某种类型的字符串。

    Here's a link to the doc on pipe

    在您的情况下的使用示例可能类似于:

    const req = request(...);
    req.pipe(dst);
    req.pipe(hash);
    

    请注意,您仍然必须处理每个流的错误,因为它们没有传播,并且如果出现可读错误,目的地也不会关闭。

    【讨论】:

    • 谢谢!引用文档“可以将多个可写流附加到单个可读流。”就是这个!我知道pipe(),但看起来我错过了这个设施。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 2019-04-02
    • 2015-06-12
    相关资源
    最近更新 更多