流上的 .pipe 和管道有啥区别
Posted
技术标签:
【中文标题】流上的 .pipe 和管道有啥区别【英文标题】:What's the difference between .pipe and pipeline on streams流上的 .pipe 和管道有什么区别 【发布时间】:2020-03-11 12:37:28 【问题描述】:我在 node.js 中找到了两种不同的管道流方式
众所周知的.pipe()
流方法
https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options
流的独立功能
https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback
我应该使用哪一个,这两者之间有什么好处?
【问题讨论】:
【参考方案1】:TL;DR - 你最好使用pipeline
什么是管道?
From the docs:一种模块方法,用于在流之间进行管道转发错误并正确清理,并在管道完成时提供回调。
使用管道的动机是什么?
❌ 我们来看看下面的代码:
const createReadStream = require('fs');
const createServer = require('http');
const server = createServer(
(req, res) =>
createReadStream(__filename).pipe(res);
);
server.listen(3000);
这里有什么问题? 如果响应将退出或客户端关闭连接 - 那么读取流未关闭或销毁,这会导致内存泄漏。
✅因此,如果您使用pipeline
,它将关闭所有其他流并确保没有内存泄漏。
const createReadStream = require('fs');
const createServer = require('http');
const pipeline = require('stream');
const server = createServer(
(req, res) =>
pipeline(
createReadStream(__filename),
res,
err =>
if (err)
console.error('Pipeline failed.', err);
else
console.log('Pipeline succeeded.');
);
);
server.listen(3000);
【讨论】:
【参考方案2】:根据文档,他们都做同样的事情。但也有一些不同:
.pipe()
是Readable
的方法,而pipeline
是stream
的模块方法,接受流到管道。
pipeline()
方法在管道完成时提供回调。
pipeline()
方法是从 node 10 版本开始添加的,而.pipe
从最早版本的 node 开始存在。
在我看来,pipeline()
的代码看起来更简洁一些,但你可以同时使用它们。
.pipe()
的示例:
const fs = require('fs');
const r = fs.createReadStream('file.txt');
const z = zlib.createGzip();
const w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);
pipeline()
的例子:
const pipeline = require('stream');
const fs = require('fs');
const zlib = require('zlib');
pipeline(
fs.createReadStream('archive.tar'),
zlib.createGzip(),
fs.createWriteStream('archive.tar.gz'),
(err) =>
if (err)
console.error('Pipeline failed.', err);
else
console.log('Pipeline succeeded.');
);
【讨论】:
【参考方案3】:pipeline 是 pipe 的改进版本,它自 Node.js v10 起被添加到流模块
此外,pipeline 接受任意数量的参数,最后一个参数是一个回调,用于了解管道何时结束或引发错误。
使用管道:
mySourceStream.pipe(myStream).pipe(anotherStream)
使用管道:
mySourceStream.pipeline(myStream, anotherStream, err =>
if (err)
console.log('There is an error')
else
console.log('pipeline successful')
)
【讨论】:
以上是关于流上的 .pipe 和管道有啥区别的主要内容,如果未能解决你的问题,请参考以下文章
sklearn Pipeline 和 DataFrameMapper 有啥区别?
Windows中的命名管道,FILE_FLAG_OVERLAPPED和PIPE_NOWAIT之间的区别
subprocess.call() 和 subprocess.Popen() 之间有啥区别使 PIPE 对前者的安全性降低?