管道传输到可写流时暂停可读流

Posted

技术标签:

【中文标题】管道传输到可写流时暂停可读流【英文标题】:Pause readable stream when piped to writable stream 【发布时间】:2021-03-03 08:35:54 【问题描述】:

我有一个可读的流,我想暂停。它通过管道传输到可写流。我的代码是这样的

const  get  = require('https');
const  createWriteStream ;

const writableStream = createWriteStream(SOME_PATH);
get(SOME_URL, (res) => 
  res.pipe(writableStream);
  setTimeout(() => 
    res.pause();
  , 2000);

  setTimeout(() => 
    res.resume();
  , 4000);
);

这在 Mac 上运行良好。但由于某种原因,在 Windows 上从https URL 下载时,这不会暂停。

我认为这是因为我的可读流通过管道传输到可写流,而可写流要求更多数据,从而恢复流。如果我取消管道,这将解决问题。这是我取消管道时的代码

const writableStream = createWriteStream(SOME_PATH);
get(SOME_URL, (res) => 
  res.pipe(writableStream);
  setTimeout(() => 
    res.unpipe(writableStream);
    res.pause();
  , 2000);

  setTimeout(() => 
    res.pipe(writableStream);
    res.resume();
  , 4000);
);

这实际上导致我的下载暂停。但这产生了一个新问题。在调用res.unpipe() 后,我仍然得到数据事件。这意味着在调用res.unpipe()res.pause() 之间的几毫秒,我的一些数据被发送到res 管道,但没有写入writableStream 管道。这以我下载的文件损坏而告终。

有没有办法解决这个问题?我不赞成拆管的想法,这只是我能想出的唯一解决方案。

我正在考虑存储res 在未通过管道传输到writableStream 时获取的数据,并在它们再次通过管道传输时手动将其传递给writableStream。这甚至可能吗?如果没有,我还有其他方法可以在通过管道传输到可读流时暂停流吗?

【问题讨论】:

【参考方案1】:

我想通了。我不确定为什么这个解决方案有效,但它对我有用。我没有在暂停之前取消管道,而是为pause 创建了一个侦听器并在那里取消管道。另外,我还手动将res.readableFlowing设置为false。通过这两个添加,我能够暂停和恢复,而不会破坏下载文件。这是实现

let isPaused = false;
const writableStream = createWriteStream(SOME_PATH);
get(SOME_URL, (res) => 
  res.pipe(writableStream);
  setTimeout(() => 
    isPaused = true;
    res.pause();
  , 2000);

  setTimeout(() => 
    isPaused = false;
    res.pipe(writableStream);
    res.resume();
  , 4000);

  res.on('pause', () => 
    // Add this flag because pause event gets called many times, and we only
    // want this code to happen when we call it manually
    if (isPaused) 
      res.unPipe(writableStream);
      res.readableFlowing = false;
    
  );
);

【讨论】:

以上是关于管道传输到可写流时暂停可读流的主要内容,如果未能解决你的问题,请参考以下文章

如何在node.js中将数组值作为可读流发出/管道?

nodejs fs 读取文件流一次读取多少数据

nodejs的流总结

Node.js 将相同的可读流输送到多个(可写)目标中

node.js 利用流实现读写同步,边读边写

Node.js 全局对象Buffer对象流