为什么fs.createReadStream只能pipe一次?

我想要pipefs.createReadStream两次,代码在这里:

 fs.createReadStream('pdf-sample1.pdf') .pipe(fs.createWriteStream('pdf-sample2.pdf')) .pipe(fs.createWriteStream('pdf-sample3.pdf')) 

但是我遇到了一个错误:

 Error: Cannot pipe. Not readable. at WriteStream.Writable.pipe (_stream_writable.js:162:22) at repl:1:86 at REPLServer.defaultEval (repl.js:132:27) at bound (domain.js:254:14) at REPLServer.runBound [as eval] (domain.js:267:12) at REPLServer.<anonymous> (repl.js:279:12) at REPLServer.emit (events.js:107:17) at REPLServer.Interface._onLine (readline.js:214:10) at REPLServer.Interface._line (readline.js:553:8) at REPLServer.Interface._ttyWrite (readline.js:830:14) 

谁能告诉我原因?

您不能将可读stream传送到另一个可读stream。 stream程是:

 readable.pipe(writable); 

一个可写的,是这种情况,可能是:

  • 可写入的stream ;
  • 双stream ;
  • 或一个转换stream 。

所以,如果你想读取多个文件并将它们传递给一个可写入的stream,那么你必须将每个文件传递给可写入的stream,并传递end: false ,因为默认情况下,可读stream将结束可写stream当没有更多的数据要读取。 这是一个例子:

 var ws = fs.createWriteStream('output.pdf'); fs.createReadStream('pdf-sample1.pdf').pipe(ws, { end: false }); fs.createReadStream('pdf-sample2.pdf').pipe(ws, { end: false }); fs.createReadStream('pdf-sample3.pdf').pipe(ws); 

当然,这不是最好的办法,你可以实现一个函数来以更通用的方式来包装这个逻辑,也许有一个循环或一个recursion的解决scheme 。

一个更简单的解决scheme是使用已经解决了这个问题的模块,就像这里一样 。