rename() 是原子的么

时间:2021-04-01 19:29:16

对一个文件做修改, 通常认为 直接 open-seek-write-write-close 不是原子的. 

1. write 本身 不一定是原子的:

    https://blogs.msdn.microsoft.com/adioltean/2005/12/28/how-to-do-atomic-writes-in-a-file/

2. 多次write, 在中间fail(app/os crash), 则修改肯定不是原子的.

 

一般通过 拷贝tmp文件 - 直接rename tmp到原文件来实现. 

rename通过来说, 直接修改 file system metadata, 如inode信息. 在posix里, rename一定是原子的, 即:

* rename成功, 原文件名 指向 temp 文件; 原文件内容被删除.

* rename失败, 原文件名 仍指向原来的文件内容.

http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html

 That specification requires that the action of the function be atomic.

 

那么, windows系统呢?  对应的函数应该是 MoveFileEx. 

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/449bb49d-8acc-48dc-a46f-0760ceddbfc3/movefileexmovefilereplaceexisting-ntfs-same-volume-atomic?forum=windowssdk

Q: This question arises often when atomic modifications to files are required, but my searching the internet didn't yield any conclusive results. Some people claim that MoveFileEx can *never* provide atomic behaviour, no matter what circumstances, but usually without any references/proof. Other people claim it can, but again without references/proof.

A: I would guess that all major filesystems (including NTFS and FAT) implement rename-within-the-same-directory as a single metadata operation. Metadata operations are always atomic (they either happen, do not happen, or corrupt the filesystem).