file - 是否有一种独立于操作系统的方式来自动覆盖文件?

标签 file go atomic

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

我最初的想法是:

  1. 使用随机生成的大 ID 写入临时文件以避免冲突。
  2. Rename临时文件名 -> 新路径名。

最佳答案

os.Rename电话 syscall.Rename对于 Linux/UNIX,它使用重命名系统调用(原子*)。在 Windows 上 syscall.Rename电话 MoveFileW假设源和目标在同一设备上(可以安排)并且文件系统是 NTFS (通常是这种情况)是原子*。

我会注意确保源和目标位于同一设备上,这样 Linux 重命名不会失败,而 Windows 重命名实际上是原子的。正如 Dave C 在上面提到的那样,在与现有文件相同的目录中创建临时文件(通常使用 ioutil.TempFile )是可行的方法;这就是我进行原子重命名的方式。

这适用于我的用例:

  1. 一个 Go 进程获取更新并重命名文件以交换更新。
  2. 另一个 Go 进程正在使用 fsnotify 监视文件更新并重新mmap s 更新时的文件。

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

进一步阅读:

  1. Is rename() atomic? “是和否。假设操作系统不崩溃,rename() 是原子的……”
  2. 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/

相关文章:

c++ - OpenMP减少子句不适用于循环计数很大的int

安卓;检查文件是否存在而不创建新文件

json - 在 Golang 中将任何 JSON 值解码为字符串

go - 虹膜 GO : Get form urlencoded data not working

json - Go - 即时修改 JSON

c++ - std::generate_n 算法需要复制 ctor。如何在下面的代码中避免这种情况?

Android java.lang.IllegalArgumentException : no char field 'exponential' in android 2. 3

c - 如何在c中获取文件长度?

bash - 对多个目录中的视频文件进行递归编码

c - 字节数组中的原子设置位