0

C# を使用して、あるディレクトリから別のディレクトリにファイルをコピーしています。私は msdn のコードを使用していますが、いくつかのギグをコピーするのに 1 分ほどかかります。エクスプローラーで数秒しかかかりません。 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 を使用すると、エクスプローラーや xcopy よりも 1 分もかからずに 6 ギガバイトをコピーできました。


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

uが使用しているのは再帰です。それは常にシステムを遅くします。

再帰がないのでこれを使用してください。

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

ここでtrue、はファイルが存在する場合は上書きすることを意味します。

これに基づいて、既存のファイルを上書きするのはアプリの場合だと思います。

あなたがするなら、ものはより速く行くはずです

  • 最初に宛先ディレクトリの名前を一時的な一意の名前に変更します
  • ソースをdestにコピーした後(上書きなし)

成功した場合は一時ディレクトリを削除し、失敗した場合はコピーされたすべてのファイルを削除し、一時の名前を元の名前に変更します。

より速くする必要があります。

幸運を。

于 2012-04-04T15:35:48.087 に答える
0

@Oded は正しいと思います。コピーと移動を比較しています。

やっていることをシェルと同じにしたい場合はSHFileOperation、または (Vista 以降の場合)を調べることができますIFileOperation。少なくとも私の知る限り、SHFileOperationP/Invoke 経由で使用する必要があります。IFileOperation は COM インターフェイスです。

于 2012-04-04T15:42:33.213 に答える
0

ディレクトリの作成で Parallel.ForEach ループを使用することには大きな問題があります。最初に注意する必要があるのは、サブディレクトリが他のディレクトリ内にネストされていることです。Parallel が順不同でディレクトリを作成すると、コードがスローされる可能性があります。ディレクトリレベル6がまだ作成されていないときに、ディレクトリレベル8を作成します。

于 2014-09-18T11:39:36.853 に答える