Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 模拟文件。如果目标已存在,则移动_C#_File_Copy - Fatal编程技术网

C# 模拟文件。如果目标已存在,则移动

C# 模拟文件。如果目标已存在,则移动,c#,file,copy,C#,File,Copy,根据以下文件: 请注意,如果试图通过将同名文件移动到该目录来替换文件,则会出现IOException。不能使用移动方法覆盖现有文件 简言之,您不能在移动时覆盖文件,因此为了便于移动时覆盖,我会通过执行文件来模拟这种行为。复制,然后执行文件。删除。比如: if (File.Exists(dstFileName)) { // System.IO.File.Move cannot be used to overwrite existing files, so we're going /

根据以下文件:

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

简言之,您不能在移动时覆盖
文件,因此为了便于移动时覆盖,我会通过执行
文件来模拟这种行为。复制
,然后执行
文件。删除
。比如:

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
不会返回任何在任何情况下都不会成功抛出异常的内容。有没有人遇到过不正确的情况?

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

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


在正常操作过程中,这是安全的。

我建议您首先检查目标文件是否存在,如果存在,请将其删除。然后执行正常的移动操作


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

如果操作系统没有提供良好的原子操作,则很难模拟原子操作<代码>移动
在某些但不是所有的文件系统上是原子的,但在磁盘之间移动时不是原子的

对于同一个磁盘,
Delete
+
Move
有点优雅(快速且安全),因为它实际上不会以任何方式填充数据。你可以进一步扩展到

try
{
    Move(dest, tmp);
    Move(src, dest);
    Delete(tmp);
}
catch
{
    try
    {
        Move(tmp, dest);
    }
    catch
    {
    }
    throw;
}
(例如,当您没有完成移动所需的权限时,这样就不太可能丢失目标文件。)

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

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


如果是:将“Target”移动到temp dir,在那里您可以确保移动会成功。您可以在Temp中生成名为auf an UUID的subdir。然后复制文件。

正确的方法是调用

File.Replace(source, destination, copy)

对我来说,这就是诀窍

如果目标文件存在,对其进行删除,然后像最初那样进行移动,难道不是更安全吗?@Tudor-不一定。如果移动失败,那么原始目标文件也将消失,这并不是预期的行为。但从你的问题我推断,如果移动允许你覆盖文件(如果它存在),你将使用它,而不是复制+删除。所以我假设您愿意冒这个风险?当然,如果它支持覆盖,我会使用
File.Move
。但是,如果它支持覆盖,我希望它在移动失败时回滚。所以在我看来风险很小,但这可能就是答案。。。与其删除目标,不如将其重命名。您知道File.Replace是在后台复制数据,还是只是更新文件系统引用(如移动)?更具体地说,当源和目标位于同一个磁盘上且拷贝为空时,它是否会像移动一样快?是的,这似乎是一个原子(或至少是事务)操作。请看,这就是.net上调用的
rename()
。然而,这不是一个原子操作。也就是说,如果我们处于删除和移动文件的中间,并且发生断电,我们就丢失了内容。这不是假设,而是我们的一个应用程序的实际问题。请参阅下面的答案,使用File.Replace()代替标题,就像大多数人问这个问题一样,您需要原子性,请参阅。