0

我正在使用 C# 将文件从一个目录复制到另一个目录。我正在使用来自 msdn 的代码,但复制几个演出需要一分钟左右的时间非常慢。在资源管理器中只需几秒钟。 http://channel9.msdn.com/Forums/TechOff/257490-How-Copy-directories-in-C Surly 有更快的方法..:)

        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,我能够在不到一分钟的时间内复制 6gigs,比 explorer 和 xcopy 快。


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

4 回答 4

5

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

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

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));
}
于 2012-04-04T15:50:14.667 回答
0

您的问题可能出在文件的 *overwriteé 上。我看到你打电话

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

wheretrue表示如果文件存在则覆盖该文件。

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

如果你的话,这些东西应该会更快

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

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

应该更快。

祝你好运。

于 2012-04-04T15:35:48.087 回答
0

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

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

于 2012-04-04T15:42:33.213 回答
0

在创建目录时使用 Parallel.ForEach 循环存在一个大问题,您需要注意的第一件事是嵌套在其他目录中的子目录,如果 Parallel 创建目录乱序,代码可能会因为试图创建目录级别 8,而目录级别 6 甚至还没有创建。

于 2014-09-18T11:39:36.853 回答