C 跨平台 renameat2() 重命名如果不存在的功能
C cross-platform renameat2() rename-if-not-exists functionality
是否有非平台特定的方法来执行原子操作 "rename File1 to File2 if File2 does not exist, otherwise give an error"?我知道我可以检查 File2 是否存在,如果不存在则重命名文件,但是当其他进程在检查和 rename()
.
之间创建 File2 时,这会引入潜在的竞争条件
在 Linux 下有 renameat2()
函数,它通过设置 RENAME_NOREPLACE
标志来完成此操作。不幸的是,联机帮助页说
renameat2() is Linux-specific.
我什至不知道是所有的 libc 实现都支持这个调用,还是只支持 glibc。
对于我的用例,在同一目录内重命名就足够了,我不需要支持移动到完全不同的路径。
这可能与 and
有关
Is there a non-platform-specific way of doing an atomic "rename File1 to File2 if File2 does not exist, otherwise give an error"?
C 标准库仅提供 rename()
用于更改文件名,并且标准关于该函数是这样说的: "If a file named by the string pointed to by new
exists prior to the call to the rename
function, the behavior is implementation-defined." 因此,如果 "non-platform-specific" 被解释为 "specified by the C standard" 那就不行,没有这个机制
如果我们扩大 "non-platform-specific" 的范围以允许 POSIX 指定的设施,那么您可以依赖 link()
,
shall atomically create a new link for the existing file and the link count of the file shall be incremented by one.
[and]
shall fail if
[... the second argument] resolves to an existing directory entry or refers to a symbolic link.
因此,您可以先为文件创建一个新的(硬的)link,如果指定的路径名指定一个现有文件或符号 link,则失败,然后删除原来的 [=33] =] 成功后。
您可能感兴趣的最著名的非 POSIX 平台是 Windows。我不确定是否有任何方法可以完成你在 Windows 上的要求,但如果有,你可以考虑编写一个使用条件编译的包装函数 select [=36] =] 或 Windows 实施。
是否有非平台特定的方法来执行原子操作 "rename File1 to File2 if File2 does not exist, otherwise give an error"?我知道我可以检查 File2 是否存在,如果不存在则重命名文件,但是当其他进程在检查和 rename()
.
在 Linux 下有 renameat2()
函数,它通过设置 RENAME_NOREPLACE
标志来完成此操作。不幸的是,联机帮助页说
renameat2() is Linux-specific.
我什至不知道是所有的 libc 实现都支持这个调用,还是只支持 glibc。
对于我的用例,在同一目录内重命名就足够了,我不需要支持移动到完全不同的路径。
这可能与 and
Is there a non-platform-specific way of doing an atomic "rename File1 to File2 if File2 does not exist, otherwise give an error"?
C 标准库仅提供 rename()
用于更改文件名,并且标准关于该函数是这样说的: "If a file named by the string pointed to by new
exists prior to the call to the rename
function, the behavior is implementation-defined." 因此,如果 "non-platform-specific" 被解释为 "specified by the C standard" 那就不行,没有这个机制
如果我们扩大 "non-platform-specific" 的范围以允许 POSIX 指定的设施,那么您可以依赖 link()
,
shall atomically create a new link for the existing file and the link count of the file shall be incremented by one. [and] shall fail if [... the second argument] resolves to an existing directory entry or refers to a symbolic link.
因此,您可以先为文件创建一个新的(硬的)link,如果指定的路径名指定一个现有文件或符号 link,则失败,然后删除原来的 [=33] =] 成功后。
您可能感兴趣的最著名的非 POSIX 平台是 Windows。我不确定是否有任何方法可以完成你在 Windows 上的要求,但如果有,你可以考虑编写一个使用条件编译的包装函数 select [=36] =] 或 Windows 实施。