如何在Node.js中把一个可读流同时管成两个可写流?

问题描述 投票:32回答:3

我们的目标是

  1. 创建一个文件读取流
  2. 将其管道化为gzip (zlib.createGzip())
  3. 然后将zlib输出的读取流用管道输送到。

    1) HTTP response 对象

    2) 可写文件流来保存gzipped输出。

现在我可以做下到3.1:

var gzip = zlib.createGzip(),
    sourceFileStream = fs.createReadStream(sourceFilePath),
    targetFileStream = fs.createWriteStream(targetFilePath);

response.setHeader('Content-Encoding', 'gzip');

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

...工作得很好,但我还需要... 将压缩后的数据保存到一个文件中 这样我就不需要每次都重新压缩,可以直接将gzipped的数据作为响应流。

那么,在Node中,我如何将一个可读流管成两个可写流同时使用?

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

node.js gzip zlib gzipstream node.js-stream
3个回答
53
投票

管道分链并不像你在这里试图做的那样工作,将第一个发送到两个不同的后续步骤。

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

然而,你可以把同一个可读的流管成两个可写的流,例如:

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

17
投票

我发现zlib会返回一个可读的流,它可以在以后被管道化成其他多个流。所以我做了下面的工作来解决上述问题。

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

0
投票

你可以使用 "readable-stream-clone "软件包

const fs = require("fs");
const ReadableStreamClone = require("readable-stream-clone");

const readStream = fs.createReadStream('text.txt');

const readStream1 = new ReadableStreamClone(readStream);
const readStream2 = new ReadableStreamClone(readStream);

const writeStream1 = fs.createWriteStream('sample1.txt');
const writeStream2 = fs.createWriteStream('sample2.txt');

readStream1.pipe(writeStream1)
readStream2.pipe(writeStream2)
© www.soinside.com 2019 - 2024. All rights reserved.