From the documentation of File.Move:
Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an IOEx
This is safe. File.Copy will either succeed entirely or throw. Of course, the delete could fail leaving the source file behind as garbage.
If your computer crashes, though, there is no guarantee that the copy oepration has hardened the data yet. You might loose data in that case.
During normal operations this is safe.
The correct way to do it would be to call
File.Replace(source, destination, copy)
That does the trick for me
It is difficult to simulate an atomic operation if the operating system doesn't give you good atomic operations. Move
is atomic on some but not all filesystems, but not when you are moving disk to disk.
In case of the same disk, Delete
+ Move
is somewhat elegant (fast and safe) as it does not really stuffle the data in any way. You could further extend it to
try
{
Move(dest, tmp);
Move(src, dest);
Delete(tmp);
}
catch
{
try
{
Move(tmp, dest);
}
catch
{
}
throw;
}
(This makes it less likely that you will lose the destination file when you for example do not have the rights necessary to finish the move.)
In a scenario where you do not know that it is the same disk, your solution is safe enough and simple enough. However, it copies the data even within the same disk, bringing you a wider window of risk of a power failure.
Check if file "Target" Exsists. If no, copy your file.
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.
I suggest you to probe first if the target file exists and if yes, delete it. Then execute a normal move operation.
Since this sequence is not atomic, in case the destination exists you might want to rename it instead of deleting it, to avoid losing it in case the move fails.