我可以在结束前关闭节点 readStream 吗?

Posted

技术标签:

【中文标题】我可以在结束前关闭节点 readStream 吗?【英文标题】:Can I close a node readStream before end? 【发布时间】:2013-12-10 17:04:17 【问题描述】:

我将fs.createReadStream 放到一个大文件中。

我可以中途停止流吗?

我在doco 中没有看到一个,并尝试调用stream.end() 但它仍然处理整个文件,并且stream.close()undefined

任何帮助都会很棒,谢谢。

【问题讨论】:

什么节点版本? close() 为我工作 正如@vkurchatkin 所说,close() 应该做你想做的事,这会关闭底层文件,因此不会读取更多数据。你看到了什么与此相矛盾的地方? 一旦我有更多时间进行测试,我必须回到这个问题上。 How to close a readable stream?的可能重复 【参考方案1】:

编辑:

从代码 cmets 可以看出,目前无法通过设计:https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L884

根据文档,一种可能的解决方案是使用偏移量:http://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

读取文件的最后 10 字节的示例,即 100 字节 长: fs.createReadStream('sample.txt', start: 90, end: 99);

【讨论】:

我不想读取预定的字节长度或偏移量;我正在根据内容做其他逻辑。不过感谢您的回答。 你能遍历流直到找到你要找的东西吗?即读取一定数量的字节。如果不存在,请更改偏移量并重试? 我更愿意按照问题要求做:关闭一个打开的流。 您将无法使用流来做到这一点。流是一个全有或全无的 IO 进程。它对您正在查看的数据一无所知。例如,在偏移量的情况下,它将扫描文件以确定长度,然后检索您想要的字节。因此,在“中间”停止流会留下无用的损坏数据。 如果我已经拿出了我需要的东西也不是没用的。如果我处于非流动模式,而不是在我准备好数据时调用 read,我说我们永远不会为该数据做好准备,只是停止流数据。您能在文档中找到流被设计为“全有或全无 IO 进程”的文档吗?【参考方案2】:

根据How to close a readable stream (before end)?,有可能,你可以在readStream上调用close(),它会在结束前关闭。我写了一个简单的脚本来测试它:

var fs = require('fs');

var l = 0

var rs = fs.createReadStream("some large file")
    .on("data", function(data)
        console.log("got data");
        l += data.length;
        if (l > 655360) 
            rs.close();
            console.log("close");
        
    )
    .on("end", function()
        console.log("shouldn't be logged");
    );

输出:

got data
got data
got data
got data
got data
got data
got data
got data
got data
got data
got data
close
got data
close

虽然close 被打印了两次,但它确实结束了 readStream。

【讨论】:

【参考方案3】:

stream.destroy() 可能是你想要的。更多详情here.

【讨论】:

以上是关于我可以在结束前关闭节点 readStream 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 中的 fs.ReadStream 和 fs.createReadStream 有啥区别吗?

Mongoose 阻止节点脚本结束

Mongoose 阻止节点脚本结束

有n个节点的有向图中的最大边数是多少? [关闭]

(node:40872) [DEP0135] DeprecationWarning: ReadStream.prototype.open() 已弃用

父线程 在创建了子线程后,是否继续执行自己的代码?它可以在子线程结束前 结束吗?