ter*_*orn 62 windows winapi posix
在POSIX系统上,rename(2)提供原子重命名操作,包括覆盖目标文件(如果存在)以及权限是否允许.
有没有办法在Windows上获得相同的语义?我知道Vista和Server 2008上的MoveFileTransacted(),但我需要它来支持Win2k及更高版本.
这里的关键词是原子 ......解决方案不能以任何方式使操作失败,使操作处于不一致状态.
我见过很多人说在win32上这是不可能的,但我问你,是不是真的?
如果可能,请提供可靠的引用.
小智 33
请参阅ReplaceFile()Win32(http://research.microsoft.com/pubs/64525/tr-2006-45.pdf)
Ada*_*vis 16
Win32不保证原子文件元数据操作.我会提供一个引用,但没有 - 这个事实是没有书面或文件保证意味着同样多.
你将不得不编写自己的例程来支持这一点.这是不幸的,但你不能指望win32提供这种服务水平 - 它根本就不是为它设计的.
小智 15
在Windows Vista和Windows Server 2008中添加了原子移动功能 - MoveFileTransacted()
不幸的是,这对旧版本的Windows没有帮助.
你仍然在Windows上进行rename()调用,虽然我想你不知道你正在使用的文件系统就无法做出你想要的保证 - 如果你使用FAT就不能保证.
但是,您可以使用MoveFileEx并使用MOVEFILE_REPLACE_EXISTING和MOVEFILE_WRITE_THROUGH选项.后者在MSDN中有这样的描述:
设置此值可确保在函数返回之前将作为复制和删除操作执行的移动刷新到磁盘.刷新发生在复制操作结束时.
我知道这不一定与重命名操作相同,但我认为这可能是你得到的最好的保证 - 如果它为文件移动做的那样,它应该用于更简单的重命名.
MSDN 文档避免明确说明哪些 API 是原子的,哪些不是,但 Niall Douglas 在他的Cppcon 2015 演讲中指出唯一的原子函数是
与FILE_RENAME_INFO.ReplaceIfExists设置为true。它从 Windows Vista / 2008 Server 开始可用。
Niall 是一个高度复杂的LLFIO 库的作者,并且是文件系统竞争条件方面的专家,所以我相信如果你正在编写一个原子性至关重要的算法,最好是安全而不是抱歉并使用建议的函数,即使ReplaceFile's 中没有描述指出它不是原子的。
从Windows 10 1607开始,NTFS确实支持原子取代重命名操作。为此,请调用NtSetInformationFile(...,FileRenameInformationEx,...)并指定FILE_RENAME_POSIX_SEMANTICS标志。或等效地在Win32中调用SetFileInformationByHandle(...,FileRenameInfoEx,...)并指定FILE_RENAME_FLAG_POSIX_SEMANTICS标志。
| 归档时间: |
|
| 查看次数: |
22408 次 |
| 最近记录: |