File copy using robo copy and process
Asked Answered
A

6

16

I am creating a File copy program which will copy large number of files(~100,000) with size ~50 KB using ROBOCOPY command.

For each file, I am creating a new process and passing the ROBOCOPY command and arguments as follow:

using (Process p = new Process)
{
    p.StartInfo.Arguments = string.Format("/C ROBOCOPY {0} {1} {2}", 
            sourceDir, destinationDir, fileName);
    p.StartInfo.FileName = "CMD.EXE";
    p.StartInfo.CreateNoWindow = true;
    p.StartInfo.UseShellExecute = false;                    
    p.Start();
    p.WaitForExit(); 
} 

Instead of creating a process for each file, I am looking for a better approach, which will be good in terms of performance and design. Can someone suggest a better method?

Avaria answered 25/10, 2011 at 14:21 Comment(5)
Why would you not just use the File.Copy() method?Idiotic
What are your requirements? Robocopy has a lot of features (multithreading, resume, retries, etc.), which are the ones that interest you?Ingrowing
Is there a particular reason you're using RoboCopy?Microampere
ROBYCOPY is faster than File.CopyAvaria
Right. ROBOCOPY is a nice tool. Please look at this benchmark mickputley.net/2014/04/robocopy-benchmarks.htmlLauro
O
2

I would just use System.IO. Should be plenty fast enough, and your filename could be a wildcard.

using System.IO;
// snip your code... providing fileName, sourceDir, destinationDir
DirectoryInfo dirInfo = new DirectoryInfo(sourceDir);
FileInfo[] fileInfos = dirInfo.GetFiles(fileName);
foreach (FileInfo file in fileInfos)
{
    File.Copy(file.FullName, Path.Combine(destinationDir, file.Name), true);  // overwrites existing
}
Operculum answered 25/10, 2011 at 14:39 Comment(5)
File.Copy is really slow when compared to ROBOCOPY. Right?Avaria
Probably not considering how the original question is posed. Shelling out to a process and waiting for it is probably slower overall. Considering some of the other comments, may want to still consider doing the File.Copy, but be creative in how you fire off the copy process. Possibly consider using a separate thread to do the copying unattended.Operculum
Your answer is not useful since File.copy does not have all features of robocopy. for eg: Longpath supportGros
This wasn' t the questionAspasia
This would block the main thread when u try to copy files through networkHonduras
M
25

This question is a bit old but I thought I would answer to help anyone who still land on it. I wrote a library called RoboSharp (https://github.com/tjscience/RoboSharp) that brings all of the goodness in Robocopy to c#. Take a look if you require the power of Robocopy in c#.

Moulding answered 22/4, 2014 at 4:7 Comment(2)
Awesome! Does everything I've been looking for!Keister
Hi I see this and it looks good but do you have a proper documentation on how to run this package? I referenced your wiki but it has a very short code snippet and for an inexperienced coder like myself, I have no idea why or how I would use void backup_OnFileProcessed(object sender, FileProcessedEventArgs e) to copy files. The only way to use your library is contained here: github.com/tjscience/RoboSharp/wiki/Code-Snippets-(C%23) And there just isn't enough info on how to use it from start to finish. Or a description of what's going on on each step @MouldingSkycap
S
6
Process p = new Process();
p.StartInfo.Arguments = string.Format("/C Robocopy /S {0} {1}", "C:\\source", "C:\\destination");
p.StartInfo.FileName = "CMD.EXE";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.Start();
p.WaitForExit(); 

/C Robocopy -> this is a command to run robocopy
/S -> This will help to copy sub folders as well as Files
Stereotype answered 28/7, 2016 at 6:55 Comment(0)
R
2

You should call File.Copy in a loop.

Rosanarosane answered 25/10, 2011 at 14:24 Comment(1)
And if he doesn't want to block main thread, he could do this job in a separate thread (maybe a BackgroundWorker) which notifies UI...Microampere
O
2

I would just use System.IO. Should be plenty fast enough, and your filename could be a wildcard.

using System.IO;
// snip your code... providing fileName, sourceDir, destinationDir
DirectoryInfo dirInfo = new DirectoryInfo(sourceDir);
FileInfo[] fileInfos = dirInfo.GetFiles(fileName);
foreach (FileInfo file in fileInfos)
{
    File.Copy(file.FullName, Path.Combine(destinationDir, file.Name), true);  // overwrites existing
}
Operculum answered 25/10, 2011 at 14:39 Comment(5)
File.Copy is really slow when compared to ROBOCOPY. Right?Avaria
Probably not considering how the original question is posed. Shelling out to a process and waiting for it is probably slower overall. Considering some of the other comments, may want to still consider doing the File.Copy, but be creative in how you fire off the copy process. Possibly consider using a separate thread to do the copying unattended.Operculum
Your answer is not useful since File.copy does not have all features of robocopy. for eg: Longpath supportGros
This wasn' t the questionAspasia
This would block the main thread when u try to copy files through networkHonduras
H
0

Robocopy can use up to 128 thread by itself. It makes a huge difference. By default it uses 8.

See https://pureinfotech.com/robocopy-multithreaded-file-copy-windows-10/

Harlow answered 11/2, 2023 at 22:50 Comment(0)
S
-1

.cmd has following lines

Start ROBOCOY src dest a* b* c*    /z /w:1 r:1
Start ROBOCOY src dest d* e* f* g* /z /w:1 r:1
Start ROBOCOY src dest h* K* P* Y*  /z /w:1 r:1
Start ROBOCOY src dest xry* srp*  /z /w:1 r:1

When I run > Robocopy sample.cmd I starts with 4 multiple windows copying files simultaneously as per above commands, it waits for another file, as it has wait time, if file is being used by another process. Is is more faster as it do job simultaneously.

Now I am developing GUI using C# windows to run the process instead going to command console and
start

  main()
  { 
  process.start( "path of sample.cmd" )
  process.waitforexit()
  label.text=" sucessful copy"
  }

However, if it takes control of one process, i.e. cmd.exe and and there are 4 robocopy processes in taskmanager. when cmd.exe process completes, it returns the cursor to label.text "Sucesssfully completed". While there are robocopy processes still running. you can see the robocopy windows doing the copying process.

Here is the question: I want to take control of all the processes (cmd.exe and robocopy.exe) programatically in C#, so that when the label.text should display "successfully completed" only when all commands are successfully completed", if one fails, then there is no point in the GUI.

option 2 (similar to Biju has written above): is it better to remove robocopy command scripts from sample.cmd(batch file) file and write code to run the 4 robocopy lines in C#, but how to run the robocooy script line written .cmd file, as they have arguments as well. I code runs each robocopy process then each will return to the next line of code and if it fails, we can catch the error and display in the message box.

Hope this will help... However, I am looking for more better way, if somebody can improve on the same.

Sahara answered 3/9, 2013 at 6:56 Comment(2)
@user2045570 Why didn't you remove the empty lines while you're at it?Nealon
@TobiasKienzler must have missed it. Will watch out for empty lines next time.Borecole

© 2022 - 2024 — McMap. All rights reserved.