如何在Node.js中将一个可读的stream一次写入两个可写的stream?

目标是:

  1. 创build一个文件读取stream。
  2. 将其pipe理到gzip( zlib.createGzip()
  3. 然后将读取的zlib输出stream传递给:

    1)HTTP response对象

    2) 可写文件stream来保存压缩的输出。

现在我可以做到3.1:

 var gzip = zlib.createGzip(), sourceFileStream = fs.createReadStream(sourceFilePath), targetFileStream = fs.createWriteStream(targetFilePath); response.setHeader('Content-Encoding', 'gzip'); sourceFileStream.pipe(gzip).pipe(response); 

…这工作正常,但我还需要将gzip压缩的数据保存到一个文件,以便我不需要每次重新压缩,并能够直接streamgzip的数据作为响应。

那么,如何在节点中将一个可读stream一次性传递到两个可写stream中?

sourceFileStream.pipe(gzip).pipe(response).pipe(targetFileStream); 在Node 0.8.x中工作?

pipe连锁/分裂不像你想要做的那样工作,发送第一个到两个不同的后续步骤:

sourceFileStream.pipe(gzip).pipe(response);

但是,您可以将相同的可读stream传送到两个可写入的stream中,例如:

 var fs = require('fs'); var source = fs.createReadStream('source.txt'); var dest1 = fs.createWriteStream('dest1.txt'); var dest2 = fs.createWriteStream('dest2.txt'); source.pipe(dest1); source.pipe(dest2); 

我发现zlib返回一个可读的stream,稍后可以将其传送到多个其他stream中。 所以我做了以下解决上述问题:

 var sourceFileStream = fs.createReadStream(sourceFile); // Even though we could chain like // sourceFileStream.pipe(zlib.createGzip()).pipe(response); // we need a stream with a gzipped data to pipe to two // other streams. var gzip = sourceFileStream.pipe(zlib.createGzip()); // This will pipe the gzipped data to response object // and automatically close the response object. gzip.pipe(response); // Then I can pipe the gzipped data to a file. gzip.pipe(fs.createWriteStream(targetFilePath));