Blankman
Blankman

Reputation: 266900

Moving files on different volumes in .NET

Apparently I can't move files on different volumes using Directory.Move.

I have read that I have to copy each file individually to the destination, then delete the source directory.

Do I have any other option?

Upvotes: 6

Views: 6000

Answers (4)

Tomas Kubes
Tomas Kubes

Reputation: 25098

Try to use this:

public static void RobustMove(string source, string destination)
{
    //move if directories are on the same volume
    if (Path.GetPathRoot(source) == Path.GetPathRoot(destination))
    {
        Directory.Move(source, destination);
    }
    else
    {        
        CopyFilesRecursively(source, destination);
        Directory.Delete(source, true);
    }
}

You will find CopyFilesRecursively function here:

This should be working until you use spanned volume or symbol links to another physical disk.

To be even more robust you can improve this function to use Move until System.IO .Exception is thrown and then to switch to copying and deleting.

Upvotes: 1

Martijn Laarman
Martijn Laarman

Reputation: 13536

To my knowledge there is no other way however deleting a directory has a catch: Read Only Files might cause a UnauthorizedAccessException when deleting a directory and all of its contents.

This recurses a directory and unsets all the read only flags. Call before Directory.Delete:

public void removeReadOnlyDeep(string directory)
{
    string[] files = Directory.GetFiles(directory);
    foreach (string file in files)
    {
        FileAttributes attributes = File.GetAttributes(file);
        if ((attributes & FileAttributes.ReadOnly) != 0)
        {
            File.SetAttributes(file, ~FileAttributes.ReadOnly);
        }
    }
    string[] dirs = Directory.GetDirectories(directory);
    foreach (string dir in dirs)
    {
        removeReadOnlyDeep(dir);
    }
}

Upvotes: 4

NePh
NePh

Reputation: 996

An easier option would be, to add a reference to the Microsoft.VisualBasic namespace and use the MoveDirectory method, which can move across volumes.

Microsoft.VisualBasic.FileIO.FileSystem.MoveDirectory(sourceDirName, destDirName);

Upvotes: 3

Kibbee
Kibbee

Reputation: 66112

Regardless of whether or not Directory.Move (or any other function) performed the move between volumes, it would essentially be doing a copy and delete anyway underneath. So if you want a speed increase, that's not going to happen. I think the best solution would be to write your own reusable move function, which would get the volume label (C:,D:) from the to and from paths, and then either perform a move, or copy+delete when necessary.

Upvotes: 6

Related Questions