os.Rename
调用 syscall.Rename
,对于 Linux/UNIX,使用重命名系统调用(原子操作 *)。在 Windows 中,syscall.Rename
调用 MoveFileW
,假定源文件和目标文件位于同一设备上(可以安排),并且文件系统为 NTFS(通常如此),也是原子操作 *。
我会注意确保源文件和目标文件位于同一设备上,以便 Linux 重命名不会失败,并且 Windows 重命名实际上是原子操作。正如 Dave C 在上面提到的那样,创建临时文件(通常使用 ioutil.TempFile
)与现有文件位于同一目录中,这是进行原子重命名的方法;这就是我进行原子重命名的方式。
对于我的用例,这对我很有效:
在上述用例中,仅使用os.Rename
对我而言就已经足够完美了。
更多阅读:
* 原文的 "atomic" 指原子操作,即操作不可分割。
*注意:我想指出,当人们谈论原子性文件系统 文件 操作时,从应用程序的角度来看,通常意味着操作发生或不发生(这可以通过日志记录来帮助),从用户的角度来看。如果您使用原子内存操作的含义,那么很少有文件系统操作被认为是真正的原子操作(除了直接 I/O [O_DIRECT] 一个块写入和读取,关闭磁盘缓存)。
ioutil.TempFile
(将dir
设置为最终目录以便重命名不涉及跨设备复制)来创建临时文件,而不是尝试生成随机文件并自己处理竞态条件。 - Dave CReplaceFile
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365512(v=vs.85).aspx,该函数支持从XP到当前版本的操作系统,但您需要将其与POSIX重命名函数的shims一起添加到自己的软件包中,以使其跨平台。更多信息请参见https://msdn.microsoft.com/en-us/library/windows/desktop/hh802690(v=vs.85).aspx。 - Intermernet