如何在 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.");
}
});
这将比:
input.on('data', function(data) {
if (isEnded) { return; }
if (gotFirstLine) {
isEnded = true;
console.log("Closed.");
}
});
但这不会阻止阅读过程...
编辑:好消息!从 Node 开始.js 8.0.0 readable.destroy
正式发布:https://nodejs.org/api/stream.html#stream_readable_destroy_error
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
没有文档(Node.js v0.12.2(,但你可以在GitHub上查看源代码(2012年10月5日提交(。
destroy
函数在内部将ReadStream
实例标记为已销毁,并调用 close
函数来释放文件。
您可以侦听 close 事件以确切了解文件何时关闭。除非数据完全消耗,否则不会触发 end 事件。
<小时 />请注意,destroy
(和close
(函数特定于 fs。读取流。没有通用流的一部分,可读的"接口"。
调用input.close()
。它不在文档中,但是
https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
显然可以:)它实际上做了一些类似于你的isEnded
的事情。
编辑 2015-Apr-19 根据下面的评论,并澄清和更新:
- 此建议是一个黑客,没有记录在案。
- 虽然查看当前
lib/fs.js
它仍然有效>1.5年后。 - 我同意下面关于称呼
destroy()
更可取的评论。 - 如下所述,这适用于
fs
ReadStreams
,而不是通用Readable
至于通用解决方案:至少从我对文档的理解和对_stream_readable.js
的快速浏览来看,似乎没有
我的建议是将您的可读流置于暂停模式,至少防止上游数据源中的进一步处理。不要忘记unpipe()
并删除所有data
事件侦听器,以便pause()
实际暂停,如 docs
今天,在节点 10 中
readableStream.destroy()
是关闭可读流的官方方式
见 https://nodejs.org/api/stream.html#stream_readable_destroy_error
在版本 4.*.*
将空值推送到流中将触发EOF
信号。
来自 nodejs 文档
如果传递了 null 以外的值,则 push(( 方法会将数据块添加到队列中,供后续流处理器使用。如果传递 null,则表示流 (EOF( 结束,之后无法再写入数据。
在此页面上尝试了许多其他选项后,这对我有用。
你不能。从节点 5.3.0 开始,没有记录的关闭/关闭/中止/销毁通用可读流的方法。这是节点流体系结构的限制。
正如这里的其他答案所解释的那样,对于 Node 提供的 Readable 的特定实现,例如 fs,存在未记录的黑客攻击。读取流。不过,这些不是任何可读的通用解决方案。
如果有人能在这里证明我是错的,请这样做。我希望能够做到我所说的不可能的事情,并且很高兴得到纠正。
编辑:这是我的解决方法:通过一系列复杂的unpipe()
调用为我的管道实现.destroy()
。在所有这些复杂性之后,它并非在所有情况下都能正常工作。
编辑:Node v8.0.0 为可读流添加了destroy()
API。
这个销毁模块旨在确保流被销毁,处理不同的 API 和 Node.js 错误。现在是最好的选择之一。
铌。从节点 10 开始,您可以使用 .destroy
方法,而无需进一步依赖。
您可以使用 yourstream.resume()
清除和关闭流,这将转储流上的所有内容并最终关闭它。
来自官方文档:
可读.resume((:
返回:此
此方法将导致可读流恢复发出"数据"事件。
此方法会将流切换到流动模式。如果您不想使用流中的数据,但确实希望访问其"结束"事件,则可以调用 stream.resume(( 来打开数据流。
var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
console.log('got to the end, but did not read anything');
});
这是一个古老的问题,但我也在寻找答案,并为我的实现找到了最好的答案。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
这里的这段代码可以很好地解决问题:
function closeReadStream(stream) {
if (!stream) return;
if (stream.close) stream.close();
else if (stream.destroy) stream.destroy();
}
writeStream.end(( 是关闭 writeStream
用于在某个调用后停止回调执行,你必须使用process.kill与特定的进程ID
const csv = require('csv-parser');
const fs = require('fs');
const filepath = "./demo.csv"
let readStream = fs.createReadStream(filepath, {
autoClose: true,
});
let MAX_LINE = 0;
readStream.on('error', (e) => {
console.log(e);
console.log("error");
})
.pipe(csv())
.on('data', (row) => {
if (MAX_LINE == 2) {
process.kill(process.pid, 'SIGTERM')
}
// console.log("not 2");
MAX_LINE++
console.log(row);
})
.on('end', () => {
// handle end of CSV
console.log("read done");
}).on("close", function () {
console.log("closed");
})