假设我有一个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.Transform
或stream.Writable
来实现类似read | calc + echo | write
的内容,但我坚持执行。
答案 0 :(得分:1)
Node.js可读流有一个.pipe
方法,它的工作方式与unix管道操作符非常相似,只是你可以流式传输js对象以及某些类型的字符串。
Here's a link to the doc on pipe
在您的案例中使用的示例可能是:
const req = request(...);
req.pipe(dst);
req.pipe(hash);
请注意,您仍然必须处理每个流的错误,因为它们不会传播,如果可读错误,则目标不会关闭。