如何关闭可读流(结束前) ?

如何在 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.");
}
});

但这不会停止阅读过程..。

136228 次浏览

调用 input.close()文件里没有,但是

Https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#l1597-l1620

它实际上和你的 isEnded差不多。

编辑部2015-4-19 根据以下评论,澄清和更新:

  • 这个建议是黑客行为,没有文档记录。
  • Though for looking at the current lib/fs.js it still works >1.5yrs later.
  • 我同意下面关于称为 destroy()更好的评论。
  • 正如下面正确陈述的那样,这适用于 fs ReadStreams,而不是一般的 Readable

至于通用解决方案: 至少从我对文档的理解和对 _stream_readable.js的快速了解来看,似乎没有这样的解决方案。

我的建议是将您的可读流放在 停顿了一下模式下,至少可以防止在您的上游数据源中进行进一步的处理。不要忘记使用 unpipe()并删除所有 data事件侦听器,这样 pause()实际上会暂停,如 那些文件中所提到的

编辑: 好消息! 从 Node.js 8.0.0开始,readable.destroy正式可用: < a href = “ https://nodejs.org/api/stream.html # stream _ readable _ broke _ error”rel = “ norefrer”> 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) ,但是您可以查看 GitHub 上的源代码(2012年10月5日)。

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

您可以监听 亲密接触以确切知道文件何时关闭。除非数据被完全消耗,否则 结束事件将不会触发。


注意,destroy(和 close)函数是特定于 Fs.ReadStream的。没有通用 流,可读“接口”的一部分。

你不能。从 Node 5.3.0开始,没有文档记录关闭/关闭/中止/销毁通用 Readable流的方法。这是 Node 流体系结构的一个局限性。

正如这里的其他答案所解释的那样,对于 Node 提供的 Readable 的特定实现(如 Fs.ReadStream) ,存在一些没有文档记录的缺陷。但是,这些并不是针对任何 Readable 的通用解决方案。

如果有人能证明我是错的,那就来吧。我希望能够做到我所说的是不可能的,并将很高兴得到纠正。

编辑 : 这是我的变通方法: 通过一系列复杂的 ABC1调用为我的管道实现 .destroy(),在所有这些复杂性之后,它是 在任何情况下都不能正常工作

编辑 : Node v8.0.0添加了一个 用于可读流的 destroy() api

您可以使用 yourstream.resume()清除和关闭流,它将转储流上的所有内容并最终关闭它。

来自 官方文件:

readable.resume():

退货: 这个

此方法将导致可读流恢复发出“数据”事件。

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.

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

At version 4.*.* pushing a null value into the stream will trigger a EOF signal.

来自 Nodejs 文件

如果传递了 null 以外的值,push ()方法将向队列中添加一个数据块,供后续流处理器使用。如果传递 null,则表示流(EOF)结束,在此之后不能再写入任何数据。

在尝试了这个页面上的许多其他选项之后,这个方法对我很有效。

这是一个老问题,但我也在寻找答案,并找到了最适合我实现的答案。endclose事件都会发出,所以我认为这是最干净的解决方案。

这将在节点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();
}

End ()是关闭 writeStream 的首选方法..。

这个 毁灭模块旨在确保一个流被销毁,处理不同的 API 和 Node.js bug。现在是最好的选择之一。

注意: 从 Node 10可以使用 .destroy方法而不需要进一步的依赖关系。

今天,在 Node 10

readableStream.destroy()

是关闭可读流的官方方式

https://nodejs.org/api/stream.html#stream_readable_destroy_error

在某个调用后停止回调执行, 必须使用 process.kill 和特定的 processID

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");
})