如果文件已经存在,我想覆盖它。如果它不存在,我想创建它并写入它。我宁愿不必使用像 lockfile 这样的第三方库(似乎可以处理所有类型的锁定。)
我最初的想法是:
- 使用随机生成的大 ID 写入临时文件以避免冲突。
- Rename临时文件名 -> 新路径名。
最佳答案
os.Rename
电话 syscall.Rename
对于 Linux/UNIX,它使用重命名系统调用(原子*)。在 Windows 上 syscall.Rename
电话 MoveFileW
假设源和目标在同一设备上(可以安排)并且文件系统是 NTFS (通常是这种情况)是原子*。
我会注意确保源和目标位于同一设备上,这样 Linux 重命名不会失败,而 Windows 重命名实际上是原子的。正如 Dave C 在上面提到的那样,在与现有文件相同的目录中创建临时文件(通常使用 ioutil.TempFile
)是可行的方法;这就是我进行原子重命名的方式。
这适用于我的用例:
在上述用例中,只需使用 os.Rename
对我来说效果很好。
进一步阅读:
- Is rename() atomic? “是和否。假设操作系统不崩溃,rename() 是原子的……”
- Is an atomic file rename (with overwrite) possible on Windows?
*注意:我确实想指出,当人们谈论原子文件系统 file 操作时,从应用程序的角度来看,他们通常意味着操作发生或不发生(journaling 可以帮助)从用户的角度来看。如果您在原子内存操作的意义上使用原子,则很少有文件系统操作(直接 I/O [O_DIRECT] 一个 block 在禁用磁盘缓冲的情况下写入和读取)可以被认为是真正原子的。
关于file - 是否有一种独立于操作系统的方式来自动覆盖文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30385225/