“Move will not work across volumes” - Why? And how

2019-01-19 00:32发布

问题:

Why is it that File.Move(sourceFileName, destFileName) works fine when the source file and destination files are in different partitions, but Directory.Move(sourceDirName, destDirName) don't? It throws

System.IO.IOException: "Source and destination path must have identical roots. Move will not work across volumes."

I even tried to create a DirectoryInfo instance and use the MoveTo(destDirName) method but without success.

Am I missing something? Do I really have to implement a "move" functionality myself? (the directory I want to move is very large btw).

回答1:

You can also p/invoke SHFileOperation which is the same function Windows Explorer uses to move directories around. It will either perform a true move or recursive-copy-then-delete, as appropriate.

It can also show the same progress UI as explorer, just by setting a flag.



回答2:

You should Use Copy Function followed by a remove. As Move only works in the same drive. Directory.Move has a condition that states that :

IO Exception will be thrown if an attempt was made to move a directory to a different volume.



回答3:

Another option is, 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);


回答4:

Although this is not a Vb.Net question but I found no one mentioned this method so I think might help... Only you need to convert it to C# if needed.

Code:

My.Computer.FileSystem.MoveDirectory(SrcDir,DestDir) 

This works on different volume seamlessly/ per my experience.



回答5:

Based on the posts "Copy a directory to a different drive" and "Non-recursive way to get all files in a directory and its subdirectories in Java", I wrote this non-recursive method and it works fine:

public static void Move(string source, string target)
    {
        if (!Directory.Exists(source))
        {
            throw new System.IO.DirectoryNotFoundException("Source directory couldn't be found.");
        }

        if (Directory.Exists(target))
        {
            throw new System.IO.IOException("Target directory already exists.");
        }

        DirectoryInfo sourceInfo = Directory.CreateDirectory(source);
        DirectoryInfo targetInfo = Directory.CreateDirectory(target);

        if (sourceInfo.FullName == targetInfo.FullName)
        {
            throw new System.IO.IOException("Source and target directories are the same.");
        }

        Stack<DirectoryInfo> sourceDirectories = new Stack<DirectoryInfo>();
        sourceDirectories.Push(sourceInfo);

        Stack<DirectoryInfo> targetDirectories = new Stack<DirectoryInfo>();
        targetDirectories.Push(targetInfo);

        while (sourceDirectories.Count > 0)
        {
            DirectoryInfo sourceDirectory = sourceDirectories.Pop();
            DirectoryInfo targetDirectory = targetDirectories.Pop();

            foreach (FileInfo file in sourceDirectory.GetFiles())
            {
                file.CopyTo(Path.Combine(targetDirectory.FullName, file.Name), overwrite: true);
            }

            foreach(DirectoryInfo subDirectory in sourceDirectory.GetDirectories())
            {
                sourceDirectories.Push(subDirectory);
                targetDirectories.Push(targetDirectory.CreateSubdirectory(subDirectory.Name));
            }
        }

        sourceInfo.Delete(true);
    }


回答6:

I know this post is a little old... but there is a way around this! Don't try and move the directory, but zip it up and move it as a File.Move(src,dest); and you can then extract it and there you have it!