节点fs.fsync(什么时候使用?)

node fs.fsync (when to use?)

我想安全地写一个文件,但我不想理解 fsync 的正确 use/place。

https://linux.die.net/man/2/fsync

看了^之后,我很困惑在哪里可以有效地使用它。

问题,我:

fs.write('temp/file.txt','utf-8',function(error){
    if(error){fs.unlink('temp/file.txt',function(){cb(error,undefined);});}
    else{
        fs.rename('temp/file.txt','real/file.txt',function(){
            fs.fsync('real/file.txt',function(){
                cb(undefined,true);
                });
            });
        }
    });

我正在写一些可以执行很多文件更改的东西。我看过写原子的模块,但我想了解这个过程。

fsync 是您极少需要使用的功能之一。

所有操作系统都通过缓存读写来掩盖存储设备速度慢的事实。当您写入文件时,它不会立即写入实际的存储介质;它会将其捕获到缓存中,告诉您的程序写入已完成,然后在后台将内容写入存储设备。操作系统会保持一切一致;如果另一个应用程序从该文件读取,它将看到新内容,因为 OS 将从缓存中提供内容。

请注意这不是普遍的;我相信 Windows 禁用可移动存储设备的缓存,以防止人们拔出驱动器时数据丢失。还有一些标志集可以传递给 open() 以禁用缓存。

对于几乎所有用例,您都不需要关心是否会发生这种情况。对您来说唯一的结果是您的程序可以更快地继续。但在某些情况下这是有问题的:

  • 如果断电,缓存中的内容也会丢失,因此磁盘将不会拥有文件的所有新内容。
  • 如果移除驱动器,写入同样会丢失。这对于可移动存储设备来说非常典型,我敢肯定 90% 的人会忽略“安全删除”提示 ;)。
  • 我认为直接从设备直接读取(即 Linux 中的 /dev/sdX)会绕过此缓存,但我不是 100% 确定。

需要它的例子是数据库。当您 运行 更新查询时,数据库通常会更新其内存状态,并将变更写入事务日志。可靠性对于数据库来说是一件好事,所以它会写入事务日志并在响应用户之前对该文件执行 fsync(或者将以无缓冲方式打开事务日志),因此有一定程度的保证事务一直坚持

在您的示例中,fsync 将确保重命名实际发生并已刷新到磁盘。