复制目录的性能

我正在使用C#将文件从一个目录复制到另一个目录。 我正在使用来自msdn的代码,但它花了一分钟左右才能复制几个演出。 在资源管理器中只需几秒钟。 http://channel9.msdn.com/Forums/TechOff/257490-How-Copy-directories-in-C有一种更快的方式.. 🙂

private static void Copy(string sourceDirectory, string targetDirectory) { DirectoryInfo diSource = new DirectoryInfo(sourceDirectory); DirectoryInfo diTarget = new DirectoryInfo(targetDirectory); CopyAll(diSource, diTarget); } private static void CopyAll(DirectoryInfo source, DirectoryInfo target) { // Check if the target directory exists, if not, create it. if (Directory.Exists(target.FullName) == false) { Directory.CreateDirectory(target.FullName); } // Copy each file into it's new directory. foreach (FileInfo fi in source.GetFiles()) { fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true); } // Copy each subdirectory using recursion. foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) { DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name); CopyAll(diSourceSubDir, nextTargetSubDir); } } 

使用Parallel我能够在比探索器和xcopy快一分钟的时间内复制6gig。


 private static void CopyAll(string SourcePath, string DestinationPath) { string[] directories = System.IO.Directory.GetDirectories(SourcePath, "*.*", SearchOption.AllDirectories); Parallel.ForEach(directories, dirPath => { Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath)); }); string[] files = System.IO.Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories); Parallel.ForEach(files, newPath => { File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath)); }); } 

你正在使用的是递归。 它总是会减慢系统的速度。

使用它,因为它没有递归。

 void CopyAll (string SourcePath, string DestinationPath) { //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 foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories)) File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath)); } 

您的问题可能是*文件的覆盖。 我看到你打电话了

 fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true); 

其中true表示覆盖文件(如果存在)。

基于此,我这是你的应用程序覆盖已有文件的情况。

如果你这些东西应该更快

  • 首先使用一些临时唯一名称重命名目标目录
  • 只是将源复制到dest(所以没有覆盖)

如果成功删除临时目录,如果失败则删除所有复制的文件并将temp重命名为其原始名称。

应该更快。

祝好运。

我怀疑@Oded是正确的,而你正在将副本与移动进行比较。

如果你想确保你所做的和shell一样,你可以查看SHFileOperation ,或者(在Vista或更新版本上) IFileOperation 。 至少据我所知,你必须通过P / Invoke使用SHFileOperation 。 IFileOperation是一个COM接口。

使用Parallel.ForEach循环创建目录存在一个很大的问题,首先需要注意的是,嵌套在其他目录中的子目录,如果Parallel无序地创建目录,则代码可能因为尝试而抛出创建目录级别8,而目录级别6甚至尚未生成。