簡體   English   中英

復制目錄的性能

[英]performance of copying directories

我正在使用 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,我能夠在一分鍾內比 explorer 和 xcopy 更快地復制 6gigs。


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表示覆蓋文件(如果存在)。

基於此,我在您的應用程序中覆蓋現有文件是一種情況。

這些東西應該 go 更快,如果你

  • 首先用一些臨時的唯一名稱重命名目標目錄
  • 在將源復制到目標之后(因此不會覆蓋)

如果成功刪除臨時目錄,如果失敗刪除所有復制的文件並將臨時文件重命名為其原始名稱。

應該更快。

祝你好運。

我懷疑@Oded 是正確的,並且您正在將副本與移動進行比較。

如果您想確保您所做的與 shell 相同,您可以查看SHFileOperation或(在 Vista 或更高版本上) IFileOperation 至少據我所知,您必須通過 P/Invoke 使用SHFileOperation IFileOperation 是一個 COM 接口。

使用 Parallel.ForEach 循環創建目錄有一個大問題,您首先需要注意的是,子目錄嵌套在其他目錄中,如果 Parallel 亂序創建目錄,則可能會拋出代碼創建目錄級別 8,而目錄級別 6 甚至還沒有創建。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM