0

我想安全地编写一个文件,但我不了解 fsync 的正确使用/位置。

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);
                });
            });
        }
    });

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

4

1 回答 1

1

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

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

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

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

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

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

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

于 2020-07-25T13:01:39.157 回答