File.Replace
是否执行原子/事务操作,以便在发生崩溃或电源故障时,目标文件永远不会丢失,也不会丢失部分文件(即原始文件或新文件)?
如果没有,是否有另一种方法可以防止这种情况发生?
注意:这将在Windows 7或更高版本的NTFS驱动器上,我知道它支持事务。
注意:我问的是保存一个原子庄园而不关心单独的进程也让文件像this question那样打开。
答案 0 :(得分:5)
File.Replace
在内部使用WinAPI函数ReplaceFile
(当然,在Windows上)。但是,即使在该函数中,原子性也不是记录在案的行为,并且文档有些含糊不清。
首先,如果您想要一致性,必须使用备份文件。根据文件:
[移动文件失败时...]如果指定了lpBackupFileName,则替换和替换文件将保留其原始文件名。否则,替换的文件不再存在,替换文件以其原始名称存在。
另一种失败模式导致
[移动文件失败时...]替换文件仍以其原始名称存在;但是,它继承了它正在替换的文件中的文件流和属性。要替换的文件仍然存在不同的名称。如果指定了lpBackupFileName,则它将是替换文件的名称。
这是最糟糕的文档行为 - 您仍然拥有这两个文件,但要“复制”的文件已经更改了其安全属性。如果您使用具有有限权限的服务来编写文件,则可能会出现问题。
最后,当删除失败时,没有任何反应。
那么,整个操作是原子的吗?即使它没有正式记录,我们也有一些指示。首先,只要您使用备份文件选项,替换操作最终是文件ID的交换(以及所有文件属性的单向更新);这是一个在NTFS上是事务性的操作,所以我的期望是这部分 实际上是原子的,只要你不必担心文件属性,ACL和备用数据流。
但是,对于File.Replace
和ReplaceFile
,此行为不符合合同规定。如果您需要一种实施跨性别操作的合同方式,则需要使用TxF。两个主要问题是,一个,TxF仅支持从Vista开始,两个,它在实践中使用不多,并且被弃用。 Bummer :)在https://msdn.microsoft.com/en-us/library/windows/desktop/hh802690%28v=vs.85%29.aspx中记录了Microsoft推荐的替代TxF的方式 - 包括使用ReplaceFile
(在.NET中公开为File.Replace
)。
答案 1 :(得分:0)
File.Replace不是原子的: https://social.msdn.microsoft.com/Forums/vstudio/en-US/848ce6b7-ce52-43ca-b79b-168835837c63/is-filereplace-atomic-on-an-ntfs-filesystem?forum=netfxbcl
“File.Replace()在内部使用对本机Windows API函数的调用ReplaceFile()” https://msdn.microsoft.com/en-us/library/windows/desktop/aa365512(v=vs.85).aspx