如何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了我的实施最好的一个。 end
和close
事件都会发出,所以我认为这是最干净的解决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之一。
- 如何从GitHub下载一个commit-diff?
- Selenium :: WebDriver :: Error :: JavascriptError:等待evaluate.js加载失败的Firefox 23