我想在C#中将目录的全部内容从一个位置复制到另一个位置.
似乎没有办法使用System.IO
没有大量递归的类来完成此操作.
VB中有一个方法,如果我们添加一个引用,我们就可以使用它Microsoft.VisualBasic
:
new Microsoft.VisualBasic.Devices.Computer(). FileSystem.CopyDirectory( sourceFolder, outputFolder );
这似乎是一个相当丑陋的黑客.有没有更好的办法?
更容易
//Now Create all of the directories foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories)) Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath)); //Copy all the files & Replaces any files with the same name foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories)) File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath), true);
嗯,我想我误解了这个问题,但我会冒风险.以下简单方法有什么问题?
public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) { foreach (DirectoryInfo dir in source.GetDirectories()) CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name)); foreach (FileInfo file in source.GetFiles()) file.CopyTo(Path.Combine(target.FullName, file.Name)); }
编辑由于这篇帖子已经为这样一个简单的答案提供了大量的downvotes同样简单的问题,让我添加一个解释.请 在downvoting之前阅读此内容.
首先,这段代码不是故意替代问题中的代码.它仅用于说明目的.
Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory
做一些额外的正确性测试(例如,源和目标是否是有效目录,源是否是目标的父目录等),这个答案中缺少这些测试.该代码可能也更加优化.
也就是说,代码运行良好.它已经(几乎相同)已经在一个成熟的软件使用多年.除了所有IO处理中存在的固有的浮躁(例如,如果用户在代码写入时手动拔出USB驱动器会发生什么情况?),没有已知的问题.
特别是,我想指出在这里使用递归绝对不是问题.理论上(从概念上讲,它是最优雅的解决方案)也不是在实践中:这段代码不会溢出堆栈.堆栈足够大,可以处理甚至深度嵌套的文件层次结构.在堆栈空间成为问题之前很久,文件夹路径长度限制就开始了.
请注意,恶意用户可能会通过使用每个字母的深层嵌套目录来打破此假设.我没试过这个.但只是为了说明这一点:为了使这个代码在典型的计算机上溢出,这些目录必须嵌套几千次.这根本不是一个现实的场景.
从MSDN复制:
using System; using System.IO; class CopyDir { public static void Copy(string sourceDirectory, string targetDirectory) { DirectoryInfo diSource = new DirectoryInfo(sourceDirectory); DirectoryInfo diTarget = new DirectoryInfo(targetDirectory); CopyAll(diSource, diTarget); } public static void CopyAll(DirectoryInfo source, DirectoryInfo target) { Directory.CreateDirectory(target.FullName); // Copy each file into the new directory. foreach (FileInfo fi in source.GetFiles()) { Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name); fi.CopyTo(Path.Combine(target.FullName, fi.Name), true); } // Copy each subdirectory using recursion. foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) { DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name); CopyAll(diSourceSubDir, nextTargetSubDir); } } public static void Main() { string sourceDirectory = @"c:\sourceDirectory"; string targetDirectory = @"c:\targetDirectory"; Copy(sourceDirectory, targetDirectory); } // Output will vary based on the contents of the source directory. }
试试这个:
Process proc = new Process(); proc.StartInfo.UseShellExecute = true; proc.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "xcopy.exe"); proc.StartInfo.Arguments = @"C:\source C:\destination /E /I"; proc.Start();
你的xcopy参数可能会有所不同,但你明白了.
或者,如果您想要努力,请为Microsoft.VisualBasic添加对项目的引用,然后使用以下命令:
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(fromDirectory, toDirectory);
但是,使用其中一个递归函数是一种更好的方法,因为它不必加载VB dll.
这个网站总是帮助我很多,现在轮到我用我所知道的帮助其他人了.
我希望下面的代码对某人有用.
string source_dir = @"E:\"; string destination_dir = @"C:\"; // substring is to remove destination_dir absolute path (E:\). // Create subdirectory structure in destination foreach (string dir in System.IO.Directory.GetDirectories(source_dir, "*", System.IO.SearchOption.AllDirectories)) { System.IO.Directory.CreateDirectory(System.IO.Path.Combine(destination_dir, dir.Substring(source_dir.Length + 1))); // Example: // > C:\sources (and not C:\E:\sources) } foreach (string file_name in System.IO.Directory.GetFiles(source_dir, "*", System.IO.SearchOption.AllDirectories)) { System.IO.File.Copy(file_name, System.IO.Path.Combine(destination_dir, file_name.Substring(source_dir.Length + 1))); }
递归复制文件夹而不进行递归以避免堆栈溢出.
public static void CopyDirectory(string source, string target) { var stack = new Stack(); stack.Push(new Folders(source, target)); while (stack.Count > 0) { var folders = stack.Pop(); Directory.CreateDirectory(folders.Target); foreach (var file in Directory.GetFiles(folders.Source, "*.*")) { File.Copy(file, Path.Combine(folders.Target, Path.GetFileName(file))); } foreach (var folder in Directory.GetDirectories(folders.Source)) { stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder)))); } } } public class Folders { public string Source { get; private set; } public string Target { get; private set; } public Folders(string source, string target) { Source = source; Target = target; } }
这是我用于此类IO任务的实用程序类.
using System; using System.Runtime.InteropServices; namespace MyNameSpace { public class ShellFileOperation { private static String StringArrayToMultiString(String[] stringArray) { String multiString = ""; if (stringArray == null) return ""; for (int i=0 ; i