Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# &引用;移动将无法跨卷运行";-为什么?如何克服?_C#_File_Directory - Fatal编程技术网

C# &引用;移动将无法跨卷运行";-为什么?如何克服?

C# &引用;移动将无法跨卷运行";-为什么?如何克服?,c#,file,directory,C#,File,Directory,为什么当源文件和目标文件位于不同的分区中时,File.Move(sourceFileName,destFileName)可以正常工作,而Directory.Move(sourceDirName,destDirName)不能正常工作?它抛出 System.IO.IOException:“源路径和目标路径必须具有 相同的根。移动不会跨卷工作。“ 我甚至尝试创建一个DirectoryInfo实例并使用MoveTo(destDirName)方法,但没有成功 我错过什么了吗?我真的必须自己实现“移动”功能

为什么当源文件和目标文件位于不同的分区中时,
File.Move(sourceFileName,destFileName)
可以正常工作,而
Directory.Move(sourceDirName,destDirName)
不能正常工作?它抛出

System.IO.IOException:“源路径和目标路径必须具有 相同的根。移动不会跨卷工作。“

我甚至尝试创建一个
DirectoryInfo
实例并使用
MoveTo(destDirName)
方法,但没有成功

我错过什么了吗?我真的必须自己实现“移动”功能吗?(顺便说一句,我要移动的目录非常大)。

您应该先使用函数,然后再使用remove。As仅在同一驱动器中工作。
Directory.Move
具有以下条件:

如果试图将目录移动到其他卷,将引发IO异常

您还可以p/invoke,这与Windows资源管理器用于移动目录的功能相同。它将执行真正的移动或递归复制,然后根据需要删除


它还可以显示与资源管理器相同的进度UI,只需设置一个标志。

另一个选项是,添加对
Microsoft.VisualBasic
命名空间的引用,并使用可以跨卷移动的
MoveDirectory
方法

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

虽然这不是一个Vb.Net问题,但我发现没有人提到这个方法,所以我认为可能会有帮助。。。如果需要,只需将其转换为C

代码:

根据我的经验,这种方法可以在不同的卷上无缝地工作。

基于文章“”和“”,我编写了这种非递归方法,它可以很好地工作:

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);
    }
publicstaticvoidmove(字符串源、字符串目标)
{
如果(!Directory.Exists(source))
{
抛出新System.IO.DirectoryNotFoundException(“找不到源目录”);
}
if(目录.Exists(目标))
{
抛出新的System.IO.IOException(“目标目录已经存在。”);
}
DirectoryInfo sourceInfo=Directory.CreateDirectory(source);
DirectoryInfo targetInfo=目录.CreateDirectory(目标);
if(sourceInfo.FullName==targetInfo.FullName)
{
抛出新的System.IO.IOException(“源目录和目标目录相同”);
}
Stack sourceDirectories=new Stack();
sourceDirectories.Push(sourceInfo);
Stack targetDirectories=new Stack();
targetDirectory.Push(targetInfo);
而(sourceDirectories.Count>0)
{
DirectoryInfo sourceDirectory=sourceDirectories.Pop();
DirectoryInfo targetDirectory=targetDirectories.Pop();
foreach(sourceDirectory.GetFiles()中的FileInfo文件)
{
CopyTo(Path.Combine(targetDirectory.FullName,file.Name),overwrite:true);
}
foreach(sourceDirectory.GetDirectories()中的DirectoryInfo子目录)
{
sourceDirectories.Push(子目录);
Push(targetDirectory.CreateSubdirectory(subDirectory.Name));
}
}
sourceInfo.Delete(true);
}

我知道这篇文章有点老了。。。但这是有办法的!不要尝试移动目录,而是将其压缩并作为
文件.move(src,dest)移动然后你可以提取它,你就有了它

我在VB.NET中也遇到了同样的问题,我使用带有“FileSystemObject”的MoveFolder代替了“Directory.Move”。 可以使用此方法保留创建日期

Scripting.FileSystemObject oFSO = new Scripting.FileSystemObject();
oFSO.MoveFolder(sourceDirName, destDirName)

我有这个问题要解决,我喜欢用这种方式来解决它

 string startPath = @".\start";
        string zipPath = @".\result.zip";
        string extractPath = @".\extract";

        ZipFile.CreateFromDirectory(startPath, zipPath);

        ZipFile.ExtractToDirectory(zipPath, extractPath);

这是因为它使用本机API:需要注意的一点是,当目标位于不同的卷上时,MoveFile函数将在目录移动时失败。我会
Process.Start
XCopy并重定向标准输出以监控流程,尤其是对于大目录。我认为
File.Move
确实有效,但
Directory.Move
不起作用是一种可能的实现疏忽。@firsttimer:pinvoke.net非常适合调用Win32 API:谢谢。我尝试一下。当我从C:移动到U盘时,它似乎保留了创建日期,但当我从U盘移动到C:驱动器时,它使用了一个新日期。你知道为什么吗?@KyleDelaney是使用与C:drive相同的文件系统的USB驱动器?@Marc.2377-我无法检查两年前的U盘,假设你不想更改目录的创建日期。此外,你的
复制
链接已断开。有没有一个
目录.Copy
功能?我试过了,它没有保留创建日期,所以我猜它仍然在幕后进行复制/删除。在我看来,这是最简单、最好的解决方案。谢谢分享。@MousaAlfhaily欢迎您,我很高兴它帮助了您:)您不太可能最终获得任何投票支持此建议。这个答案已经有了公认的答案。您提出的解决方案与其他答案存在相同的问题,但更为复杂+1,因为使用此方法可以保留目录创建日期。至少在使用7z进行测试时。
 string startPath = @".\start";
        string zipPath = @".\result.zip";
        string extractPath = @".\extract";

        ZipFile.CreateFromDirectory(startPath, zipPath);

        ZipFile.ExtractToDirectory(zipPath, extractPath);