【问题标题】:Nodejs fs.createReadStream event errorNodejs fs.createReadStream 事件错误
【发布时间】:2018-06-27 14:32:37
【问题描述】:

我正在尝试非常快速地从文件中读取数据(来自 ADC 的数据)。转换在打开文件时开始,并在关闭时完成。我需要等待再次打开文件,等待当前转换完成。

我的问题是,当我很快打开文件时,nodejs 不会捕捉到预期的事件。任何线索如何解决这个问题?

 node.on('input', function(){

            readStream = fs.createReadStream(path.location,{encoding: 'utf8'});

            if (readyFlag == 1) {
                readStream.on('data',(data) => {
                    data = {payload: data/1000};
                    node.send(data);
                    console.log(`data: ${data}`);

                })
            }

            readStream.on('open', () => {
                console.log("file opened");
                readyFlag = 0;
            })   



            readStream.on('close', () => {
                console.log("file closed");
                readyFlag = 1;
            })

            readStream.on('error', (err) => {
                console.log(err);
            })




    })

我最终发现文件一直在打开。

【问题讨论】:

  • 你到底想在这里做什么?您是否试图保护文件上的多次读取?有点令人困惑,至于为什么文件保持打开状态,可能是因为您正在传递选项而不是设置 autoClose: true - 根据 the docs 它应该默认为,但只有当您根本没有传递任何选项时才会发生这种情况.
  • 我可以看到它有点混乱。对不起!事实上,是的,我试图防止多次读取。我想确保文件已关闭,然后才能进行另一次读取操作。当我在 1 秒内打开和关闭文件时,我的代码有效。但如果我强制它每 0.1 秒读取一次,它只会收到“打开”事件,而不会收到“关闭”事件。

标签: javascript node.js readfile node-red


【解决方案1】:

所以在我看来,这里的问题是 readStream 的上下文 - 它不是 input 回调的本地内容,这意味着每条消息都会覆盖对前一个流的引用。

当你增加消息的频率时这开始失败的事实对我来说似乎是合乎逻辑的,因为流还没有机会完成,所以readyFlag 永远不会重置。

这个问题的修复应该是一个单行,使流成为本地变量

const readStream = ...

【讨论】:

  • 它不止于此,因为当'data' 事件可以注册为readStream 时,readyFlag 将始终为 0,除非它被初始化为 1。此外,不应将 readyFlag 限定为范围与readStream 相同,因为它是该流的标志?
  • 谢谢。说得通!我明天试试。对您的评论:我已将标志初始化为等于 1。但是您对范围是正确的。明天我也会改变它。谢谢!
  • @peteb 我假设readyFlag 正在其他地方被初始化,否则它根本不起作用......我认为readyFlag 需要在全球范围内,因为每条传入的消息都需要摆脱那个状态。
【解决方案2】:

我想我已经解决了。 readyFlag 对于输入范围必须是全局的,否则它将不起作用。我在 if 语句中移动了“open”事件,该语句正在检查 readyFlag。这似乎解决了问题。现在系统不会挂起,文件只是在完成读取并关闭之前打开的部分后才被打开。

代码如下:

    var readyFlag = 1;
    node.on('input', function(msg){

            const readStream = fs.createReadStream(path.location,{encoding: 'utf8'});


            if (readyFlag == 1) {
                readStream.on('data',(data) => {
                    data = {payload: data/1000};
                    node.send(data);
                    console.log('data read');
                    readyFlag = 0;

                })

                readStream.on('open', () => {
                    console.log("file opened");

                })   
            }

            readStream.on('close', () => {
                console.log("file closed");
                readyFlag = 1;
            })

            readStream.on('error', (err) => {
                console.log(err);
            })
    })

【讨论】:

  • 不确定我是否同意这一点 - 你是说如果你不让 readStream 成为本地 var 这行得通吗?我不明白为什么将readStream.on('open', ...) 单独移动到if 会在这里产生任何影响,修复是根据我的回答使readStream 成为本地变量。
  • 嗨@James 我一整天都在处理这个问题。不幸的是,我的解决方案没有按预期工作。当然不是!一般来说,我对 JavaScript 和 node.js 还是很陌生,所以对我来说很简单。我现在明白了,readyFlag 在这种情况下没有任何作用,因为 if 语句中的所有操作都是异步的。好吧..刚刚删除了对readyFlag的检查。主要问题是,如果我使用 node.send(data) 对象,该节点红色流编辑器 Web 服务正在关闭。如果我只在console.log上输出就没有问题了
  • 听起来像 Node-Red 正在崩溃,很难说是什么原因造成的,因为它可能是另一个节点,因为它发生在 node.send - 但是,如果文件不再处于打开状态,听起来我喜欢问题中详述的问题由于本地变量而得到修复。
猜你喜欢
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 2018-12-10
  • 1970-01-01
相关资源
最近更新 更多