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



如何在 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

在版本 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');
});

这是一个古老的问题,但我也在寻找答案,并为我的实现找到了最好的答案。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();
}

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

相关内容

  • 没有找到相关文章

最新更新