Reputation:
I am using C# to copy files from one directory to another directory. I am using code from msdn but its pretty slow taking a minute or so to copy a couple of gigs. It only takes seconds in explorer. http://channel9.msdn.com/Forums/TechOff/257490-How-Copy-directories-in-C Surly there a faster way..:)
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);
}
}
Using Parallel I was able to copy 6gigs in under a minute faster than explorer and 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));
});
}
Upvotes: 0
Views: 4233
Reputation: 552
There is a big problem with using Parallel.ForEach loops with creating directories, the first thing you need to be aware of, are sub directories nested within other directories, if Parallel creates directories out of order, the code can be thrown due to trying to create directory level 8 while directory level 6 was not even made yet.
Upvotes: 0
Reputation: 48558
What u are using is recursion. It always slows the system.
Use this as it has no recursion.
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));
}
Upvotes: 5
Reputation: 490108
I suspect @Oded is correct, and you're comparing a copy to a move.
If you want to ensure that what you're doing is the same as the shell does, you could look into SHFileOperation
, or (on Vista or newer) IFileOperation
. At least as far as I know, you'd have to use SHFileOperation
via P/Invoke. IFileOperation is a COM interface.
Upvotes: 0
Reputation: 62248
Your issue is probabbly on *overwriteé of the file. I see that you call
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
where true
means overwrite the file if it exists.
Based on this I suppose so that it's a case in your app to overwrite already existing files.
The stuff should go faster if you
if success remove temp directory, if fails remove all copied files and rename temp to its original name.
Should be faster.
Good luck.
Upvotes: 0