.pipe和流中的管道有什么区别

时间:2019-11-15 11:02:05

标签: node.js stream

我发现了在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

我应该使用哪个?这两个之间有什么好处?

3 个答案:

答案 0 :(得分:7)

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);

答案 1 :(得分:1)

管道管道的改进版本,自Node.js v10起已添加到流模块中。

此外,管道接受任意数量的参数,最后一个参数是用于知道管道何时结束或引发错误的回调。

使用管道:

mySourceStream.pipe(myStream).pipe(anotherStream)

使用管道:

mySourceStream.pipeline(myStream, anotherStream, err => {
  if (err) {
    console.log('There is an error')
 } else {
    else console.log('pipeline successful')
 }
})

答案 2 :(得分:0)

根据文档,它们都做相同的事情。但是有一些区别:

  • .pipe()Readable的方法,而pipelinestream的模块方法,它接受要传递的流。
  • pipeline()方法在管道完成时提供回调。
  • 从节点的10版本开始添加了
  • pipeline()方法,而从节点的最早版本开始存在.pipe

我认为,使用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.');
    }
  }
);