File.Move不起作用 - 文件已经存在

时间:2011-05-07 12:01:49

标签: c# file-io

我有一个文件夹:

  

C:\测试

我正在尝试这段代码:

File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test");

我得到例外:

  

文件已存在

输出目录肯定存在,输入文件就在那里。

9 个答案:

答案 0 :(得分:122)

您需要的是:

if (!File.Exists(@"c:\test\Test\SomeFile.txt")) {
    File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");
}

if (File.Exists(@"c:\test\Test\SomeFile.txt")) {
    File.Delete(@"c:\test\Test\SomeFile.txt");
}
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");

这将:

  • 如果文件在目标位置不存在,请成功移动文件,或者;
  • 如果文件确实存在于目标位置,请将其删除,然后移动文件。

编辑:我应该澄清我的答案,即使它是最受欢迎的! File.Move的第二个参数应该是目标文件 - 不是文件夹。您将第二个参数指定为目标文件夹,目标文件名 - 这是File.Move所需的。 因此,您的第二个参数应为c:\test\Test\SomeFile.txt

答案 1 :(得分:56)

您需要将其移动到另一个文件(而不是文件夹),这也可以用来重命名。

移动:

File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");

重命名:

File.Move(@"c:\test\SomeFile.txt", @"c:\test\SomeFile2.txt");

在您的示例中说“文件已存在”的原因是因为C:\test\Test尝试创建没有扩展名的文件Test,但由于已存在同名文件夹而无法执行此操作

答案 2 :(得分:26)

我个人更喜欢这种方法。 这将覆盖目标上的文件,删除源文件,并防止在复制失败时删除源文件。

string source = @"c:\test\SomeFile.txt";
string destination = @"c:\test\test\SomeFile.txt";

try
{
    File.Copy(source, destination, true);
    File.Delete(source);
}
catch
{
    //some error handling
}

答案 3 :(得分:10)

您可以对MoveFileEx()进行P / Invoke - 为flags传递 11 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern bool MoveFileEx(string existingFileName, string newFileName, int flags);

或者,您可以致电

Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(existingFileName, newFileName, true);

添加Microsoft.VisualBasic作为参考。

答案 4 :(得分:9)

如果文件确实存在并且您想要替换它,请使用以下代码:

string file = "c:\test\SomeFile.txt"
string moveTo = "c:\test\test\SomeFile.txt"

if (File.Exists(moveTo))
{
    File.Delete(moveTo);
}

File.Move(file, moveTo);

答案 5 :(得分:4)

根据the docs for File.Move,没有“覆盖if exists”参数。您尝试指定目标文件夹,但您必须提供完整的文件规范。

再次阅读文档(“提供指定新文件名的选项”),我认为,在目标文件夹规范中添加反斜杠可能有效。

答案 6 :(得分:4)

1)在.Net Core 3.0及更高版本上使用C#,现在有了第三个布尔参数:

请参阅https://docs.microsoft.com/en-us/dotnet/api/system.io.file.move?view=netcore-3.1

In .NET Core 3.0 and later versions, you can call Move(String, String, Boolean) setting the parameter overwrite to true, which will replace the file if it exists.

2)对于.Net的所有其他版本,https://stackoverflow.com/a/42224803/887092是最佳答案。复制并覆盖,然后删除源文件。这样做更好,因为它使其成为原子操作。 (我试图以此来更新MS文档)

答案 7 :(得分:1)

如果您没有选择删除新位置中已经存在的文件,但是仍然需要从原始位置移动和删除,则此重命名技巧可能会起作用:

string newFileLocation = @"c:\test\Test\SomeFile.txt";

while (File.Exists(newFileLocation)) {
    newFileLocation = newFileLocation.Split('.')[0] + "_copy." + newFileLocation.Split('.')[1];
}
File.Move(@"c:\test\SomeFile.txt", newFileLocation);

这假定唯一的“。”文件名中的扩展名之前。 它将文件扩展名一分为二,并附加“ _copy”。在两者之间。 这使您可以移动文件,但是如果文件已经存在或副本的副本已经存在,或者副本的副本存在,则创建副本...;)

答案 8 :(得分:0)

试试Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(Source, Destination, True)。最后一个参数是覆盖开关,System.IO.File.Move没有。