node.js 如何关闭可读流(结束前)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19277094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to close a readable stream (before end)?
提问by Ionic? Biz?u
How to close a readable streamin Node.js?
如何关闭Node.js 中的可读流?
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.");
}
});
This would be better than:
这会比:
input.on('data', function(data) {
if (isEnded) { return; }
if (gotFirstLine) {
isEnded = true;
console.log("Closed.");
}
});
But this would not stop the reading process...
但这不会停止阅读过程......
采纳答案by Nitzan Shaked
Invoke input.close(). It's not in the docs, but
调用input.close(). 它不在文档中,但是
https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
clearly does the job :) It actually does something similar to your isEnded.
显然可以完成这项工作:) 它实际上与您的isEnded.
EDIT 2015-Apr-19Based on comments below, and to clarify and update:
EDIT 2015-Apr-19基于以下评论,并澄清和更新:
- This suggestion is a hack, and is not documented.
- Though for looking at the current
lib/fs.jsit still works >1.5yrs later. - I agree with the comment below about calling
destroy()being preferable. - As correctly stated below this works for
fsReadStreams's, not on a genericReadable
- 这个建议是一个黑客,没有记录。
- 尽管查看电流,
lib/fs.js它在1.5 年后仍然有效。 - 我同意下面关于打电话
destroy()更可取的评论。 - 正如下面正确所述,这适用于
fsReadStreams's,而不适用于通用Readable
As for a generic solution: it doesn't appear as if there is one, at least from my understanding of the documentation and from a quick look at _stream_readable.js.
至于通用解决方案:至少从我对文档的理解和快速浏览_stream_readable.js.
My proposal would be put your readable stream in pausedmode, at least preventing further processing in your upstream data source. Don't forget to unpipe()and remove all dataevent listeners so that pause()actually pauses, as mentioned in the docs
我的建议是将您的可读流置于暂停模式,至少防止在您的上游数据源中进行进一步处理。不要忘记unpipe()并删除所有data事件侦听器,以便pause()实际暂停,如文档中所述
回答by Yves M.
Edit:Good news! Starting with Node.js 8.0.0 readable.destroyis officially available: https://nodejs.org/api/stream.html#stream_readable_destroy_error
编辑:好消息!从 Node.js 8.0.0 开始readable.destroy正式可用:https: //nodejs.org/api/stream.html#stream_readable_destroy_error
ReadStream.destroy
读取流.destroy
You can call the ReadStream.destroyfunction at any time.
您可以随时调用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');
});
The public function ReadStream.destroyis not documented (Node.js v0.12.2) but you can have a look at the source code on GitHub(Oct 5, 2012 commit).
公共函数ReadStream.destroy没有记录(Node.js v0.12.2),但您可以查看GitHub 上的源代码(2012 年 10 月 5 日提交)。
The destroyfunction internally mark the ReadStreaminstance as destroyed and calls the closefunction to release the file.
该destroy函数在内部将ReadStream实例标记为已销毁并调用该close函数以释放文件。
You can listen to the close eventto know exactly when the file is closed. The end eventwill not fire unless the data is completely consumed.
您可以侦听close 事件以准确了解文件何时关闭。在结束事件将不会触发除非数据被完全消耗。
Note that the destroy(and the close) functions are specific to fs.ReadStream. There are not part of the generic stream.readable"interface".
请注意,destroy(和close)函数特定于fs.ReadStream。没有通用stream.readable“接口”的一部分。
回答by Jo-Go
Today, in Node 10
今天,在节点 10
readableStream.destroy()
readableStream.destroy()
is the official way to close a readable stream
是关闭可读流的官方方法
see https://nodejs.org/api/stream.html#stream_readable_destroy_error
见https://nodejs.org/api/stream.html#stream_readable_destroy_error
回答by Jacob Lowe
At version 4.*.*pushing a null value into the stream will trigger a EOFsignal.
在版本4.*.*中将空值推入流将触发EOF信号。
From the nodejs docs
If a value other than null is passed, The push() method adds a chunk of data into the queue for subsequent stream processors to consume. If null is passed, it signals the end of the stream (EOF), after which no more data can be written.
如果传入了非空值,push() 方法会在队列中添加一个数据块,供后续流处理器消费。如果传入 null,则表示流结束 (EOF),之后无法再写入数据。
This worked for me after trying numerous other options on this page.
在此页面上尝试了许多其他选项后,这对我有用。
回答by thejoshwolfe
You can't. There is no documented way to close/shutdown/abort/destroy a generic Readablestream as of Node 5.3.0. This is a limitation of the Node stream architecture.
你不能。从 Node 5.3.0 开始,没有记录的方法来关闭/关闭/中止/销毁通用可读流。这是 Node 流架构的一个限制。
As other answers here have explained, there are undocumented hacks for specific implementations of Readable provided by Node, such as fs.ReadStream. These are not generic solutions for any Readable though.
正如此处的其他答案所解释的那样,对于 Node 提供的 Readable 的特定实现,例如fs.ReadStream,存在未记录的黑客攻击。这些不是任何可读的通用解决方案。
If someone can prove me wrong here, please do. I would like to be able to do what I'm saying is impossible, and would be delighted to be corrected.
如果有人可以在这里证明我是错的,请这样做。我希望能够做我所说的不可能的事情,并且很高兴得到纠正。
EDIT: Here was my workaround: implement .destroy()for my pipeline though a complex series of unpipe()calls.And after all that complexity, it doesn't work properly in all cases.
编辑:这是我的解决方法:通过一系列复杂的调用为我的管道实现。.destroy()unpipe()毕竟如此复杂,它并不是在所有情况下都能正常工作。
EDIT: Node v8.0.0 added a destroy()api for Readable streams.
编辑:节点 v8.0.0 添加了destroy()可读流的api。
回答by Rocco Musolino
This destroymodule is meant to ensure a stream gets destroyed, handling different APIs and Node.js bugs. Right now is one of the best choice.
这个destroy模块旨在确保流被销毁,处理不同的 API 和 Node.js 错误。现在是最好的选择之一。
NB.From Node 10 you can use the .destroymethod without further dependencies.
注意。从 Node 10 开始,您可以使用该.destroy方法而无需进一步依赖。
回答by Vexter
It's an old question but I too was looking for the answer and found the best one for my implementation. Both endand closeevents get emitted so I think this is the cleanest solution.
这是一个老问题,但我也在寻找答案,并找到了最适合我的实现的答案。无论end和close事件被发出,所以我觉得这是最干净的解决方案。
This will do the trick in node 4.4.* (stable version at the time of writing):
这将在节点 4.4.*(撰写本文时的稳定版本)中发挥作用:
var input = fs.createReadStream('lines.txt');
input.on('data', function(data) {
if (gotFirstLine) {
this.end(); // Simple isn't it?
console.log("Closed.");
}
});
For a very detailed explanation see: http://www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm
有关非常详细的解释,请参见:http: //www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm
回答by Sayem
You can clear and close the stream with yourstream.resume(), which will dump everything on the stream and eventually close it.
您可以使用 清除和关闭流yourstream.resume(),这将转储流中的所有内容并最终关闭它。
From the official docs:
来自官方文档:
readable.resume():
Return: this
This method will cause the readable stream to resume emitting 'data' events.
This method will switch the stream into flowing mode. If you do not want to consume the data from a stream, but you do want to get to its 'end' event, you can call stream.resume() to open the flow of data.
可读的.resume():
返回:这个
此方法将导致可读流恢复发射“数据”事件。
此方法会将流切换到流动模式。如果您不想使用流中的数据,但确实想获得其 'end' 事件,则可以调用 stream.resume() 来打开数据流。
var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
console.log('got to the end, but did not read anything');
});
回答by g00dnatur3
This code here will do the trick nicely:
此处的代码可以很好地解决问题:
function closeReadStream(stream) {
if (!stream) return;
if (stream.close) stream.close();
else if (stream.destroy) stream.destroy();
}
writeStream.end() is the go-to way to close a writeStream...
writeStream.end() 是关闭 writeStream 的首选方法...

