【发布时间】:2018-11-27 03:42:10
【问题描述】:
我正在编写一个与第 3 方应用程序交互的 NodeJS 脚本。第三方应用程序将在文件打开期间将数据写入文件。我希望我的 NodeJS 应用程序能够实时接收这些数据。
我的脚本创建了一个先进先出:
child_process.spawnSync('mkfifo', [pipePath]);
然后它使用child_process.spawn 启动第三方应用程序。最后,它从管道中读取数据。
let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDONLY);
let stream = fs.createReadStream(null, {fd: pipeHandle, autoClose: false});
stream.on('data', d => {
console.log(d.length);
});
如果 3rd 方应用程序正常工作,这将非常有用。但是,在某些情况下,第 3 方应用程序将退出而不会写入文件/FIFO。在这种情况下,我的脚本中的 fs.open() 调用将永远阻塞。 (参见 GitHub 上的this related issue)
为了解决这个问题,我使用了
let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK);
如果 3rd 方应用程序失败,这可以防止我的脚本挂起,但现在“数据”事件永远不会被触发,即使 3rd 方应用程序正常工作也是如此。我想知道使用 O_NONBLOCK 打开 FIFO 是否不算打开读取?
我不确定解决此问题的最佳方法是什么。目前我正在考虑启动 3rd 方应用程序,等待 10 秒,看看它是否仍在运行,然后打开 fifo 进行读取,因为如果第三方应用程序完全失败,它可能会很快失败。但这是一个 hack,所以我想知道更好的解决方案是什么。
谢谢!
【问题讨论】:
-
根据 bnoordhuis 的评论,您是否想在您的
(pipePath, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK)中 add 而不是使用按位或? (或者是他的建议中的错字?) -
@CertainPerformance
fs.constants.O_RDONLY + fs.constants.O_NONBLOCK产生相同的结果。因为它们是位掩码,所以在这种情况下,操作执行完全相同的操作。它们都评估为 2048。