使用Robocopy复制文件和进行处理

16

我正在创建一个文件复制程序,将使用ROBOCOPY命令复制大量文件(~100,000),每个文件的大小约为50KB。

对于每个文件,我都会创建一个新进程,并按以下方式传递ROBOCOPY命令和参数:

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

我不想为每个文件创建一个进程,我正在寻找更好的方法,既要考虑性能,又要考虑设计。有人能建议一个更好的方法吗?


1
为什么你不直接使用File.Copy()方法呢? - Jimmy D
你有什么要求?Robocopy有很多功能(多线程、恢复、重试等),哪些是你感兴趣的? - D'Arcy Rittich
您使用 RoboCopy 有什么特别的原因吗? - Marco
ROBYCOPY比File.Copy更快。 - Biju Thomas
好的。ROBOCOPY是一个不错的工具。请看这个基准测试 http://www.mickputley.net/2014/04/robocopy-benchmarks.html - t98907
6个回答

24

这个问题有点老了,但我认为我可以回答以帮助任何仍然遇到这个问题的人。我编写了一个名为 RoboSharp (https://github.com/tjscience/RoboSharp) 的库,将 Robocopy 中的所有优点带到了 c# 中。如果需要在 c# 中使用 Robocopy 的功能,请看一下。


1
太棒了!包含我一直在寻找的所有功能! - NielW
你好,我看到这个项目很不错,但是你有没有详细的文档说明如何运行这个包?我参考了你的维基页面,但是里面只有一个非常简短的代码片段,对于像我这样经验不足的程序员来说,我不知道为什么或者如何使用 void backup_OnFileProcessed(object sender, FileProcessedEventArgs e) 来复制文件。唯一能够使用你的库的方式在这里:https://github.com/tjscience/RoboSharp/wiki/Code-Snippets-(C%23)但是从头到尾使用它的信息并不足够,也没有每个步骤的描述。@xcopy - Datboydozy

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

2

我建议使用System.IO。它的速度足够快,而且你的文件名可以使用通配符。

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
}

7
与 ROBOCOPY 相比,File.Copy 的速度真的很慢,对吗? - Biju Thomas
可能不考虑原始问题的表述方式。启动进程并等待它可能总体上较慢。考虑到其他一些评论,可能仍然要考虑进行文件复制,但要在触发复制过程的方式上有创意。可能要考虑使用单独的线程来自动执行复制操作。 - William Stearns
6
您的回答不太有用,因为File.copy没有robocopy的所有功能,例如:长路径支持。 - Honorificabilitudinitas
2
这不是问题。 - Igor Meszaros
当您尝试通过网络复制文件时,这会阻塞主线程。 - Andy

2
你应该在循环中调用File.Copy

如果他不想阻塞主线程,他可以在单独的线程中完成这项工作(可能是BackgroundWorker),并通知UI... - Marco

0

-1

.cmd 文件有以下几行

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

当我运行> Robocopy sample.cmd时,根据上述命令,它以4个多窗口同时复制文件开始,等待另一个文件,因为它有等待时间,如果文件正在被另一个进程使用。它同时执行任务,速度更快。
现在我正在使用C# Windows开发GUI来运行该过程,而不是去命令控制台并启动。
  main()
  { 
  process.start( "path of sample.cmd" )
  process.waitforexit()
  label.text=" sucessful copy"
  }

然而,如果它控制了一个进程,比如cmd.exe,并且在任务管理器中有4个robocopy进程。当cmd.exe进程完成时,它将光标返回到label.text“成功完成”。虽然仍有robocopy进程在运行,但您可以看到robocopy窗口正在执行复制过程。

这里是问题:我想以C#编程的方式控制所有进程(cmd.exe和robocopy.exe),以便当所有命令都成功完成时,label.text应该显示“成功完成”,如果其中一个失败,则GUI没有意义。

选项2(类似于Biju上面写的):是否更好地从sample.cmd(批处理文件)文件中删除robocopy命令脚本,并编写代码在C#中运行4个robocopy行,但如何运行编写的robocooy脚本行.cmd文件,因为它们也有参数。如果我的代码运行每个robocopy进程,那么每个进程都将返回到下一行代码,如果失败,我们可以捕获错误并在消息框中显示。

希望这可以帮助... 但是,我正在寻找更好的方法,如果有人能改进相同的内容。


1
@user2045570 你为什么不趁机把空行也删掉呢? - Tobias Kienzler
@TobiasKienzler 可能错过了,下次会注意空行。 - nedaRM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接