模拟文件.如果目标已存在,则移动
本文关键字:移动 存在 文件 如果 目标 模拟 | 更新日期: 2023-09-27 18:32:04
来自File.Move
的文档:
请注意,如果尝试通过将同名文件移动到该目录中来替换文件,则会获得 IOException。不能使用 Move 方法覆盖现有文件。
简而言之,你不能在Move
上覆盖,所以为了便于在 Move 上覆盖,我通过执行一个File.Copy
然后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
不返回任何内容,因此在任何情况下它都不会成功,因此它应该抛出异常。有没有人遇到过任何不是这种情况的情况?
我建议您先探测目标文件是否存在,如果是,请将其删除。然后执行正常的移动操作。
由于此序列不是原子序列,因此如果目标存在,您可能希望重命名它而不是删除它,以避免在移动失败时丢失它。
正确的方法是调用
File.Replace(source, destination, copy)
这对我来说是
如果操作系统不能为您提供良好的原子操作,则很难模拟原子操作。 Move
在某些文件系统上是原子的,但不是在所有文件系统上是原子的,但在将磁盘移动到磁盘时则不是。
在同一个磁盘的情况下,Delete
+ Move
有点优雅(快速和安全),因为它不会以任何方式真正填充数据。 您可以进一步将其扩展到
try
{
Move(dest, tmp);
Move(src, dest);
Delete(tmp);
}
catch
{
try
{
Move(tmp, dest);
}
catch
{
}
throw;
}
(这样,当您没有完成移动所需的权限时,丢失目标文件的可能性就会降低。
在您不知道它是同一个磁盘的情况下,您的解决方案足够安全且足够简单。 但是,它甚至会在同一磁盘内复制数据,从而为您带来更大的电源故障风险窗口。
这是安全的。File.Copy 要么完全成功,要么抛出。当然,删除可能会失败,将源文件作为垃圾留下。
但是,如果您的计算机崩溃,则无法保证复制已强化数据。在这种情况下,您可能会丢失数据。
在正常操作期间,这是安全的。
检查文件"目标"是否存在。如果没有,请复制您的文件。
如果是:将"目标"移动到临时目录,在那里您可以确定移动将成功。您可以在 Temp 中生成名为 auf an UUID 的子目录。然后复制您的文件。