Jack Kada
Jack Kada

Reputation: 25192

File.Move Does Not Work - File Already Exists

I've got a folder:

c:\test

I'm trying this code:

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

I get exception:

File already exists

The output directory definitely exists and the input file is there.

Upvotes: 100

Views: 198439

Answers (9)

Mitchell
Mitchell

Reputation: 7087

Edit: Starting from .NET core 3.0, an overwrite option is available for the File.Move method, making it a preferred choice for moving files with the ability to overwrite existing files at the destination:

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

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

The File.Move method is preferred because it uses an actual NTFS command. This method not only overwrites the file at the destination but also removes the source file in a single atomic operation.

See also: https://learn.microsoft.com/en-us/dotnet/api/system.io.file.move?view=net-8.0

If you use dotnet core 2.2 or lower, the old answer still applies:

Old: This will overwrite the file on the destination, removes the source file and also prevent removing the source file when the copy fails.

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
}

Upvotes: 58

Kind Contributor
Kind Contributor

Reputation: 18533

  1. With C# on .Net Core 3.0 and beyond, there is now a third boolean parameter:

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.

Source: Microsoft Docs

  1. For all other versions of .Net, this answer is the best. Copy with Overwrite, then delete the source file. This is better because it makes it an atomic operation. (I have attempted to update the MS Docs with this)

Upvotes: 16

Yaw
Yaw

Reputation: 21

If you don't have the option to delete the already existing file in the new location, but still need to move and delete from the original location, this renaming trick might work:

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);

This assumes the only '.' in the file name is before the extension. It splits the file in two before the extension, attaches "_copy." in between. This lets you move the file, but creates a copy if the file already exists or a copy of the copy already exists, or a copy of the copy of the copy exists... ;)

Upvotes: 2

mheyman
mheyman

Reputation: 4325

You can do a P/Invoke to MoveFileEx() - pass 11 for flags (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);

Or, you can just call

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

after adding Microsoft.VisualBasic as a reference.

Upvotes: 22

Mark
Mark

Reputation: 21

Try Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(Source, Destination, True). The last parameter is Overwrite switch, which System.IO.File.Move doesn't have.

Upvotes: 2

Jamie Howarth
Jamie Howarth

Reputation: 3323

What you need is:

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

or

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");

This will either:

  • If the file doesn't exist at the destination location, successfully move the file, or;
  • If the file does exist at the destination location, delete it, then move the file.

Edit: I should clarify my answer, even though it's the most upvoted! The second parameter of File.Move should be the destination file - not a folder. You are specifying the second parameter as the destination folder, not the destination filename - which is what File.Move requires. So, your second parameter should be c:\test\Test\SomeFile.txt.

Upvotes: 167

Pawel Czapski
Pawel Czapski

Reputation: 1864

If file really exists and you want to replace it use below code:

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

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

File.Move(file, moveTo);

Upvotes: 11

Lee
Lee

Reputation: 1641

You need to move it to another file (rather than a folder), this can also be used to rename.

Move:

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

Rename:

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

The reason it says "File already exists" in your example, is because C:\test\Test tries to create a file Test without an extension, but cannot do so as a folder already exists with the same name.

Upvotes: 67

Ekkehard.Horner
Ekkehard.Horner

Reputation: 38745

According to the docs for File.Move there is no "overwrite if exists" parameter. You tried to specify the destination folder, but you have to give the full file specification.

Reading the docs again ("providing the option to specify a new file name"), I think, adding a backslash to the destination folder spec may work.

Upvotes: 5

Related Questions