如何关闭Node.js中的readable 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.");
}
});
但这不会阻止阅读过程......
答案 0 :(得分:51)
编辑:好消息!从Node.js 8.0.0 readable.destroy
开始正式提供:https://nodejs.org/api/stream.html#stream_readable_destroy_error
您可以随时调用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
(Node.js v0.12.2),但您可以查看source code on GitHub(Oct 5, 2012 commit)。
destroy
函数在内部将ReadStream
实例标记为已销毁,并调用close
函数以释放该文件。
您可以收听close event以确切知道文件何时关闭。除非数据被完全消耗,否则end event不会触发。
请注意,destroy
(以及close
)函数特定于fs.ReadStream。通用stream.readable“接口”没有部分。
答案 1 :(得分:29)
调用input.close()
。它不在文档中,而是
https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
显然可以完成工作:)它实际上与您的isEnded
类似。
编辑2015年4月19日根据以下评论,澄清并更新:
lib/fs.js
,但仍然可以使用1.5小时。destroy()
更优先的评论。fs
ReadStreams
,而不适用于通用Readable
至于通用解决方案:它似乎没有一个,至少从我对文档的理解和快速查看_stream_readable.js
开始。
我的建议是将您的可读流放入暂停模式,至少可以阻止您在上游数据源中进一步处理。不要忘记unpipe()
并删除所有data
个事件监听器,以便pause()
实际暂停,如the docs
答案 2 :(得分:15)
答案 3 :(得分:11)
你不能。从Node 5.3.0开始,没有记录的关闭/关闭/中止/销毁通用Readable流的方法。这是节点流体系结构的限制。
正如此处的其他答案所解释的那样,Node提供的Readable的具体实现还有未记录的hack,例如fs.ReadStream。这些不是任何Readable的通用解决方案。
如果有人在这里证明我错了,请这样做。我希望能够做到我所说的不可能,并且很乐意得到纠正。
编辑:以下是我的解决方法:implement .destroy()
for my pipeline though a complex series of unpipe()
calls.在完成所有这些复杂性后,doesn't work properly in all cases。
答案 4 :(得分:10)
在版本4.*.*
将空值推入流中会触发EOF
信号。
如果传递了null以外的值,则push()方法将一大块数据添加到队列中,供后续流处理器使用。如果传递null,则表示流的结尾(EOF),之后不能再写入数据。
在此页面上尝试了许多其他选项后,这对我有用。
答案 5 :(得分:4)
这个destroy模块旨在确保流被破坏,处理不同的API和Node.js错误。现在是最好的选择之一。
NB。从节点10,您可以使用.destroy
方法,而无需进一步依赖。
答案 6 :(得分:3)
您可以使用yourstream.resume()
清除和关闭流,这将转储流上的所有内容并最终将其关闭。
readable.resume():
返回:这个
此方法将使可读流恢复发送数据'事件
此方法将流切换为流动模式。如果您不想使用流中的数据,但您确实想要使用它的结尾' event,您可以调用stream.resume()来打开数据流。
var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
console.log('got to the end, but did not read anything');
});
答案 7 :(得分:3)
这是一个老问题,但我也在寻找答案,并为我的实施找到了最好的答案。 end
和close
事件都会被发出,所以我认为这是最干净的解决方案。
这将在节点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
答案 8 :(得分:2)
这里的代码很好地解决了这个问题:
function closeReadStream(stream) {
if (!stream) return;
if (stream.close) stream.close();
else if (stream.destroy) stream.destroy();
}
writeStream.end()是关闭writeStream的首选方法......