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

Gol*_*den 9 filesystems file-io acid transactional node.js

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

目前,我正在使用一个简单的fs.writeFile.

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

如果没有,我怎么能实现这样的保证?这有什么模块吗?

Mir*_*toš 8

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

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

如果没有,我怎么能实现这样的保证?这有什么模块吗?

我能想到的最简单的解决方案是用于FTP上传的解决方案:

  1. 将内容保存到具有不同名称的临时文件.
  2. 将内容写入磁盘时,将临时文件重命名为目标文件.

手册页说,重命名保证离开NEWPATH的实例到位(像Linux或OSX Unix系统).


Vit*_*aly 7

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


ver*_*loc 6

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

在挖掘的NodeJS'代码一点,人们可以看到,在fs.js,所有的包装的定义,使用fs.c其所有文件系统调用.更具体地,该write方法用于写入缓冲区的内容.事实证明,写入的POSIX规范明确地说:

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

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