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