#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, должно быть, пропустил это. В следующий раз следите за пустыми строками.