C#File.Replace可防止崩溃

时间:2016-01-08 00:45:18

标签: c# .net

File.Replace是否执行原子/事务操作,以便在发生崩溃或电源故障时,目标文件永远不会丢失,也不会丢失部分文件(即原始文件或新文件)?

如果没有,是否有另一种方法可以防止这种情况发生?

注意:这将在Windows 7或更高版本的NTFS驱动器上,我知道它支持事务。

注意:我问的是保存一个原子庄园而不关心单独的进程也让文件像this question那样打开。

2 个答案:

答案 0 :(得分:5)

File.Replace在内部使用WinAPI函数ReplaceFile(当然,在Windows上)。但是,即使在该函数中,原子性也不是记录在案的行为,并且文档有些含糊不清。

首先,如果您想要一致性,必须使用备份文件。根据文件:

  

[移动文件失败时...]如果指定了lpBackupFileName,则替换和替换文件将保留其原始文件名。否则,替换的文件不再存在,替换文件以其原始名称存在。

另一种失败模式导致

  

[移动文件失败时...]替换文件仍以其原始名称存在;但是,它继承了它正在替换的文件中的文件流和属性。要替换的文件仍然存在不同的名称。如果指定了lpBackupFileName,则它将是替换文件的名称。

这是最糟糕的文档行为 - 您仍然拥有这两个文件,但要“复制”的文件已经更改了其安全属性。如果您使用具有有限权限的服务来编写文件,则可能会出现问题。

最后,当删除失败时,没有任何反应。

那么,整个操作是原子的吗?即使它没有正式记录,我们也有一些指示。首先,只要您使用备份文件选项,替换操作最终是文件ID的交换(以及所有文件属性的单向更新);这是一个在NTFS上是事务性的操作,所以我的期望是这部分 实际上是原子的,只要你不必担心文件属性,ACL和备用数据流。

但是,对于File.ReplaceReplaceFile,此行为不符合合同规定。如果您需要一种实施跨性别操作的合同方式,则需要使用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)