Копирование файлов с помощью robo copy и процесса

#c# #windows #file #copy #robocopy

#c# #Windows #файл #Копировать #robocopy

Вопрос:

Я создаю программу копирования файлов, которая будет копировать большое количество файлов (~ 100 000) размером ~ 50 КБ с помощью команды ROBOCOPY.

Для каждого файла я создаю новый процесс и передаю команду 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. Почему бы вам просто не использовать файл. Метод Copy()?

2. Каковы ваши требования? Robocopy обладает множеством функций (многопоточность, возобновление, повторные попытки и т. Д.), Какие из них вас интересуют?

3. Есть ли особая причина, по которой вы используете RoboCopy?

4. ROBYCOPY быстрее, чем File.Copy

5. Правильно. ROBOCOPY — хороший инструмент. Пожалуйста, посмотрите на этот тест mickputley.net/2014/04/robocopy-benchmarks.html

Ответ №1:

Этот вопрос немного устарел, но я подумал, что отвечу, чтобы помочь всем, кто все еще на нем. Я написал библиотеку под названием RoboSharp (https://github.com/tjscience/RoboSharp ) это переносит все преимущества Robocopy на c #. Посмотрите, нужны ли вам возможности Robocopy в c #.

Комментарии:

1. Потрясающе! Делает все, что я искал!

2. Привет, я вижу это, и это выглядит хорошо, но есть ли у вас надлежащая документация о том, как запустить этот пакет? Я ссылался на вашу вики, но там очень короткий фрагмент кода, и для такого неопытного программиста, как я, я понятия не имею, почему и как я буду использовать void backup_OnFileProcessed(отправитель объекта, FileProcessedEventArgs e) для копирования файлов. Единственный способ использовать вашу библиотеку содержится здесь: github.com/tjscience/RoboSharp/wiki/Code-Snippets -(C#) И просто недостаточно информации о том, как использовать его от начала до конца. Или описание того, что происходит на каждом шаге @xcopy

Ответ №2:

 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
 

Ответ №3:

Я бы просто использовал 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
}
 

Комментарии:

1. Файл. Копирование происходит очень медленно по сравнению с ROBOCOPY. Верно?

2. Вероятно, не учитывая, как задан исходный вопрос. Переход к процессу и ожидание его, вероятно, в целом медленнее. Учитывая некоторые другие комментарии, возможно, вы все же захотите рассмотреть возможность создания файла. Копируйте, но будьте изобретательны в том, как вы запускаете процесс копирования. Возможно, рассмотрите возможность использования отдельного потока для автоматического копирования.

3. Ваш ответ бесполезен, поскольку File.copy не обладает всеми функциями robocopy. например: поддержка длинного пути

4. Это не был вопрос

5. Это приведет к блокировке основного потока при попытке копирования файлов через сеть

Ответ №4:

Вы должны вызывать File.Copy в цикле.

Комментарии:

1. И если он не хочет блокировать основной поток, он может выполнить эту работу в отдельном потоке (возможно, a BackgroundWorker ), который уведомляет пользовательский интерфейс…

Ответ №5:

.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
I запускается с 4-мя копированием файлов в нескольких окнах одновременно в соответствии с приведенными выше командами, он ожидает
другого файла, так как у него есть время ожидания, если файл используется другим процессом. Это
быстрее, поскольку оно выполняет работу одновременно.

Сейчас я разрабатываю графический интерфейс с использованием C # windows для запуска процесса, вместо этого перейдя в командную консоль и
запустив

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

Однако, если он берет под контроль один процесс, т.е. cmd.exe и в taskmanager есть 4 процесса robocopy
. когда cmd.exe процесс завершается, он возвращает курсор в label.text «Успешно
завершен». Пока процессы robocopy все еще запущены. вы можете видеть окна robocopy
, выполняющие процесс копирования.

Вот вопрос: я хочу взять под контроль все процессы (cmd.exe и robocopy.exe ) программно на C #, так что, когда label.text должен отображать «успешно завершено» только тогда, когда все команды успешно завершены», если один сбой, то в графическом интерфейсе нет смысла.

вариант 2 (аналогичный написанному Biju выше): лучше ли удалять командные скрипты robocopy из файла sample.cmd (пакетный файл) и писать код для запуска 4 строк robocopy на C #, но как запустить строку сценария robocooy, написанную в файле .cmd, поскольку у них также есть аргументы. I code запускает каждый процесс robocopy, затем каждый из них возвращается к следующей строке кода, и если это не удается, мы можем перехватить ошибку и отобразить в окне сообщения.

Надеюсь, это поможет… Тем не менее, я ищу более лучший способ, если кто-то может улучшить то же самое.

Комментарии:

1. @user2045570 Почему вы не удалили пустые строки, пока вы это делаете?

2. @TobiasKienzler, должно быть, пропустил это. В следующий раз следите за пустыми строками.