1

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

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

而且我想即时执行此操作,而无需在内存中缓冲整个响应。

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

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但我坚持执行。

4

1 回答 1

1

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

这是管道上文档的链接

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

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

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

于 2017-04-02T17:19:12.470 回答