在Go中,是否有一种独立于os的方式来自动覆盖文件?

lf2*_*215 6 file atomic go

如果该文件已存在,我想覆盖它.如果它不存在,我想创建它并写入它.我宁愿不必使用像lockfile这样的第三方库(它似乎可以处理所有类型的锁定.)

我最初的想法是:

  1. 写入具有随机生成的大ID的临时文件以避免冲突.
  2. 重命名临时文件名 - >新路径名.

voi*_*gic 5

os.Rename呼叫syscall.Rename,其用于Linux / UNIXs使用该重命名系统调用(这是原子*)。在Windows syscall.Rename呼叫MoveFileW哪个假设源和目的地是同一设备(其可以被布置)上并且文件系统是NTFS(这是经常的情况)是原子*。

我会确保源和目标在同一设备上,以确保Linux重命名不会失败,而Windows重命名实际上是原子的。正如Dave C所述ioutil.TempFile,在现有文件所在的目录中创建临时文件(通常使用)是可行的方法;这就是我做原子重命名的方式。

在我的用例中,这对我有用:

  1. One Go进程获取更新并重命名文件以交换更新。
  2. 别的去了过程是看与文件更新fsnotify并重新MMAP当它被更新s文件。

在上述用例中,简单的使用os.Rename对我来说效果很好。

一些进一步的阅读:

  1. 是否named()是原子的?“是的,没有。rename()是原子的,假设操作系统不会崩溃。
  2. 在Windows上可以重命名(覆盖)原子文件吗?

*注:我确实要指出,当人们从应用程序的角度谈论原子文件系统文件操作时,它们通常意味着从用户的角度来看该操作发生了还是没有发生(日记可以提供帮助)。如果您从原子内存操作的意义上使用原子,那么很少文件系统操作(在直接I / O [ O_DIRECT ]块写入和读取之外禁用磁盘缓冲的情况下)可以视为真正的原子。