以事务方式在Node.js中写入文件

时间:2013-06-11 15:27:56

标签: node.js file-io filesystems transactional acid

我有一个Node.js应用程序,它将一些配置数据存储在一个文件中。如果更改某些设置,配置文件将写入磁盘。

目前,我使用的是简单的fs.writeFile

现在我的问题是:当文件被写入时Node.js崩溃会发生什么?是否有机会在磁盘上有一个损坏的文件?或者Node.js是否保证文件是以原子方式编写的,以便旧版本或新版本有效?

如果没有,我该如何实施这样的保证?这有什么模块吗?

3 个答案:

答案 0 :(得分:8)

  

当文件被写入时,Node.js崩溃会发生什么?是   有机会在磁盘上有一个损坏的文件?或者Node.js   保证文件是以原子方式写的,所以要么   旧版本或新版本是否有效?

Node仅通过系统调用实现(精简)异步包装,因此它不提供有关写入原子性的任何保证。事实上,fs.writeAll会反复调用fs.write,直到写完所有数据。你是对的,当Node.js崩溃时,你可能会得到一个损坏的文件。

  

如果没有,我该如何实施这样的保证?这有什么模块吗?

我能想出的最简单的解决方案是使用的解决方案,例如:用于FTP上传:

  1. 将内容保存到具有不同名称的临时文件中。
  2. 将内容写入磁盘时,将临时文件重命名为目标文件。
  3. man page表示重命名保证保留新路径实例(在Linux或OSX等Unix系统上)。

答案 1 :(得分:6)

fs.writeFile,就像fs模块中的所有其他方法一样,实现为标准POSIX函数的简单包装(如docs中所述)。

在nodejs代码中挖掘一下,可以看到定义了所有包装器的fs.js对其所有文件系统调用使用fs.c。更具体地说,write方法用于写入缓冲区的内容。事实证明,写POSIX specification明确表示:

  

原子/非原子:如果写入全部数量,则写入是原子的   一个操作不与来自任何其他进程的数据交错。   当有多个写入器将数据发送到a时,这很有用   单读者。应用程序需要知道写请求的大小   期望以原子方式进行。调用此最大值   {} PIPE_BUF。 IEEE Std 1003.1-2001的这一卷没有说明是否   超过{PIPE_BUF}个字节的写请求是原子的,但需要   写入{PIPE_BUF}或更少的字节应该是原子的。

因此,只要缓冲区的大小小于PIPE_BUF,编写它似乎是非常安全的。这是一个与系统相关的常量,因此您可能需要在其他地方检查它。

答案 2 :(得分:3)

write-file-atomic会做你需要的。它写入临时文件,然后重命名。那是安全的。