fs.writeFileSync 给出错误:未知,在 nodejs 中进行同步文件写入的正确方法

Posted

技术标签:

【中文标题】fs.writeFileSync 给出错误:未知,在 nodejs 中进行同步文件写入的正确方法【英文标题】:fs.writeFileSync gives Error:UNKNOWN, correct way to make synchronous file write in nodejs 【发布时间】:2015-12-24 18:54:25 【问题描述】:

我有一个 NodeJS 服务器应用程序。我的日志记录有这行代码:

fs.writeFileSync(__dirname + "/../../logs/download.html.xml", doc.toString());

有时它可以正常工作,但在重负载下会出现此异常:

Error: UNKNOWN, unknown error 'download.html.xml'

PS:我在这里找到了一个链接:http://www.daveeddy.com/2013/03/26/synchronous-file-io-in-nodejs/ Blogger 描述 writeFileSync 在返回时并没有真正完成写入。有没有正确的同步方式,即没有回调?

【问题讨论】:

你认为什么是“正确的”? 为什么不想使用回调?执行同步操作会阻塞事件循环,而且由于您的应用负载过重,情况尤其糟糕。 @stiv 真的需要那么多重构吗?从长远来看,这可能是值得的。使用 writeFileSync 没有利用 javascript 的强大功能,也不允许您优雅地处理此问题。 你说这需要大量的重构,现在没有资源。您可以通过丢弃原始的 writeFileSync 并让它异步工作来覆盖writeFileSync,然后及时平滑迁移并在完成后回滚该功能。 @Stepan Yakovenko 你想让我把它放在回复中吗?如果它解决并可以帮助将来的搜索... 【参考方案1】:

当您执行writeFileSync 时,您将获得该文件的文件描述符。操作系统限制了在给定时间可以打开的文件描述符的数量。因此,在大量使用的情况下,您实际上可能已达到极限。找出这种情况的一种方法是使用 ulimit 并将其设置为无限制。

另一种可能性是 IO 错误。例如,如果发生 IO 错误,关闭文件描述符将失败。

【讨论】:

据我所见,达到描述符限制会导致特定错误 (EMFILE),而不是未知错误 - 所以这可能不是这里的原因。【参考方案2】:

对于 OP 似乎很欣赏该评论,我将其放在回复中,希望它可以帮助其他用户。

在我看来,问题是由于调用writeFileSync 用完了很多描述符。问题中发布的链接似乎也证实了这个想法。

实际上,我仍在试图弄清楚是否存在一种方法可以知道写入何时真正完成,而不仅仅是从 nodejs 的角度来看。 也许this 参数可以提供帮助,但我想它也遇到了同样的问题。

无论如何,可以通过实现一个 writers 池和一个队列来解决这个问题。

优点是可以控制打开描述符的数量。确实不完全是因为OP发布的链接中提到的问题,但当然可以避免耗尽系统的所有资源。

另一方面,不幸的是,存在一个问题,即这种解决方案往往会占用更多的内存(因为实际上是在等待可用的工作人员时将他的文档停在那里)。

当然,对于时间上分离的请求突发来说,这可能是一个合适的解决方案,但它可能不适合在时间上保持恒定的固定负载。

【讨论】:

以上是关于fs.writeFileSync 给出错误:未知,在 nodejs 中进行同步文件写入的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

等待承诺的 fs.writeFile 与 fs.writeFileSync

完成 fs.writeFilesync 时的回调

节点 fs.writeFileSync() 永远不会返回

Nodemon fs.writeFileSync 崩溃

nodejs写文件

[Node.js] Write or Append to a File in Node.js with fs.writeFile and fs.writeFileSync