我想安全地写入文件,但我不想了解 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);
});
});
}
});
我正在编写一些可以执行许多文件更改的内容。我已经查看了编写原子的模块,但我想了解该过程。
最佳答案
fsync
是您极少需要使用的函数之一。
所有操作系统都通过缓存读取和写入来掩盖存储设备速度缓慢的事实。当您写入文件时,它不会立即写入实际的存储介质;而是写入文件。它会将其捕获到缓存中,告诉您的程序写入已完成,然后在后台将内容写入存储设备。不过,操作系统会让一切保持一致;如果另一个应用程序读取该文件,它将看到新内容,因为操作系统将从缓存中提供内容。
请注意,这不是通用的;我相信 Windows 会禁用可移动存储设备的缓存,以防止人们拔出驱动器时丢失数据。您还可以将一些标志传递给 open()
以禁用缓存。
对于几乎所有用例,您无需关心这种情况的发生。对您来说唯一的结果是您的程序可以更快地继续。但在某些情况下这是有问题的:
- 如果断电,缓存的内容就会丢失,因此磁盘将不会包含文件的所有新内容。
- 如果驱动器被移除,写入内容同样会丢失。这对于可移动存储设备来说是非常典型的,我很确定 90% 的人都会忽略“安全删除”提示;)。
- 我认为直接从设备(即 Linux 中的/dev/sdX)直接读取将绕过此缓存,但我不能 100% 确定。
需要它的地方的例子是数据库。当您运行更新查询时,数据库通常会更新其内存中状态,并将更改写入事务日志。不过,可靠性对于数据库来说是一件好事,因此它会写入事务日志并在响应用户之前对该文件执行 fsync(或者将事务日志打开为无缓冲),因此可以在一定程度上保证事务一直坚持着。
在您的示例中,fsync
将确保重命名实际发生并已刷新到磁盘。
关于node.js - node fs.fsync(什么时候使用?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63088496/