7

从以下文档File.Move

请注意,如果您尝试通过将同名文件移动到该目录来替换文件,则会收到 IOException。您不能使用 Move 方法覆盖现有文件。

简而言之,您不能覆盖 on Move,因此为了便于在 Move 上覆盖,我通过执行 aFile.Copy后跟 a来模仿行为File.Delete。就像是:

if (File.Exists(dstFileName))
{
    // System.IO.File.Move cannot be used to overwrite existing files, so we're going
    // to simulate that behavior with a Copy & Delete.
    File.Copy(procContext.FileName, dstFileName);
    File.Delete(procContext.FileName);
}
else
    File.Move(procContext.FileName, dstFileName);

我的问题是:是否有任何我需要防范的情况可能导致源文件在没有先被成功复制的情况下被删除?

从阅读文档中我的理解是,因为File.Copy它不返回任何东西,它应该在任何情况下都没有成功抛出异常。有没有人遇到过不正确的情况?

4

5 回答 5

9

我建议你先探测目标文件是否存在,如果存在,则将其删除。然后执行正常的移动操作。

由于这个序列不是原子的,如果目标存在,您可能想要重命名它而不是删除它,以避免在移动失败时丢失它。

于 2012-04-24T20:16:27.723 回答
7

The correct way to do it would be to call

File.Replace(source, destination, copy)

That does the trick for me

于 2014-02-19T14:11:48.070 回答
4

如果操作系统没有为您提供良好的原子操作,则很难模拟原子操作。 Move在某些但不是所有文件系统上是原子的,但在将磁盘移动到磁盘时则不是。

在同一个磁盘的情况下,Delete+Move有点优雅(快速且安全),因为它不会以任何方式真正填充数据。您可以进一步将其扩展到

try
{
    Move(dest, tmp);
    Move(src, dest);
    Delete(tmp);
}
catch
{
    try
    {
        Move(tmp, dest);
    }
    catch
    {
    }
    throw;
}

(例如,当您没有完成移动所需的权限时,这样就不太可能丢失目标文件。)

在您不知道它是同一个磁盘的情况下,您的解决方案足够安全且足够简单。但是,它甚至会在同一个磁盘中复制数据,从而为您带来更大的电源故障风险窗口。

于 2012-04-24T20:24:16.400 回答
2

这是安全的。File.Copy 要么完全成功,要么抛出。当然,删除可能会失败,将源文件作为垃圾留在后面。

但是,如果您的计算机崩溃,则无法保证复制操作已经加固了数据。在这种情况下,您可能会丢失数据。

在正常操作期间,这是安全的。

于 2012-04-24T20:07:31.513 回答
0

检查文件“目标”是否存在。如果没有,请复制您的文件。

If yes: Move "Target" to temp dir, where you can be sure, that the move will be successful. You can generate a subdir in Temp with the name auf an UUID. Then copy your file.

于 2012-04-24T20:26:53.497 回答