如何closures可读stream(在结束之前)?

如何在Node.js中closures可读的stream ?

var input = fs.createReadStream('lines.txt'); input.on('data', function(data) { // after closing the stream, this will not // be called again if (gotFirstLine) { // close this stream and continue the // instructions from this if console.log("Closed."); } }); 

这会比:

 input.on('data', function(data) { if (isEnded) { return; } if (gotFirstLine) { isEnded = true; console.log("Closed."); } }); 

但这不会阻止阅读过程…

调用input.close() 。 这不是在文档中,但是

https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620

显然做的工作:)它实际上做了类似于你的isEnded

编辑2015年4月19日根据下面的评论,澄清和更新:

  • 这个build议是一个黑客,并没有logging。
  • 虽然看目前的lib/fs.js它仍然在1.5年后。
  • 我同意下面关于调用destroy()的评论。
  • 正如下面正确地指出,这适用于fs ReadStreams ,而不是通用Readable

至于通用的解决scheme:至less从我对文档的理解以及快速浏览_stream_readable.js看起来_stream_readable.js

我的build议是将您的可读stream放在暂停模式,至less阻止您的上游数据源的进一步处理。 不要忘记去掉所有data事件侦听器,以便pause()实际上暂停,正如文档中提到的那样

ReadStream.destroy

您可以随时调用ReadStream.destroy函数。

 var fs = require('fs'); var readStream = fs.createReadStream('lines.txt'); readStream .on('data', function (chunk) { console.log(chunk); readStream.destroy(); }) .on('end', function () { // This may not been called since we are destroying the stream // the first time 'data' event is received console.log('All the data in the file has been read'); }) .on('close', function (err) { console.log('Stream has been destroyed and file has been closed'); }); 

公共函数ReadStream.destroy没有logging(Node.js v0.12.2),但你可以看看GitHub上的源代码 ( 2012年10月5日提交 )。

destroy函数在内部将ReadStream实例标记为已销毁,并调用close函数释放文件。

您可以聆听closures事件以准确知道文件何时closures。 除非数据完全消耗,否则结束事件不会触发。


请注意, destroy (和close )函数特定于fs.ReadStream 。 不存在genericsstream.readable “接口”的一部分。

你不能。 从Node 5.3.0开始,没有logging的方式来closures/closures/中止/销毁通用可读stream。 这是节点stream体系结构的限制。

正如其他答案在这里解释的那样,对于由Node提供的Readable的特定实现,例如fs.ReadStream,存在未被logging的黑客攻击。 这些都不是任何可读的通用解决scheme。

如果有人在这里certificate我错了,请做。 我希望能够做到我所说的是不可能的,并且很乐意被纠正。

编辑 :这是我的解决方法: 执行.destroy()我的pipe道,虽然一个复杂的系列unpipe()调用。 毕竟这种复杂性在任何情况下都不能正常工作 。

在版本4.*.*向stream中推入一个空值将触发一个EOF信号。

从nodejs文档

如果传递的值不是null,则push()方法会将一个数据块添加到队列中供后续stream处理器使用。 如果传递null,则表示stream的结束(EOF),之后不能再写入数据。

这尝试了许多其他选项后,在这个页面上工作。

您可以使用yourstream.resume()清除并closuresstream,该stream将转储stream中的所有内容并最终closures它。

从官方文档 :

readable.resume():

返回:这个

这种方法将导致可读stream重新发射“数据”事件。

这种方法将stream切换到stream动模式。 如果您不想从stream中使用数据,但您确实想要访问其“结束”事件,则可以调用stream.resume()打开数据stream。

 var readable = getReadableStreamSomehow(); readable.resume(); readable.on('end', () => { console.log('got to the end, but did not read anything'); }); 

这是一个古老的问题,但我也在寻找答案,并find了我的实施最好的一个。 endclose事件都会发出,所以我认为这是最干净的解决scheme。

这将在节点4.4中做到这一点。*(写作时的稳定版本):

 var input = fs.createReadStream('lines.txt'); input.on('data', function(data) { if (gotFirstLine) { this.end(); // Simple isn't it? console.log("Closed."); } }); 

有关非常详细的解释,请参阅: http : //www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm

这里的代码将很好地做到这一点:

 function closeReadStream(stream) { if (!stream) return; if (stream.close) stream.close(); else if (stream.destroy) stream.destroy(); } 

writeStream.end()是closureswriteStream的前进方式…

这个销毁模块是为了确保一个stream被破坏,处理不同的API和Node.js错误。 现在是最好的select之一。