2011-10-25 16 views
8

Tworzę program do kopiowania plików, który skopiuje dużą liczbę plików (~ 100 000) o rozmiarze ~ 50 KB za pomocą polecenia ROBOCOPY.Kopiowanie pliku przy użyciu kopii robo i procesu

Dla każdego pliku, tworzę nowy proces i przechodzącej polecenia robocopy i argumenty następująco:

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

Zamiast tworzyć proces dla każdego pliku, szukam lepszego podejścia, które będą być dobry pod względem wydajności i wzornictwa. Czy ktoś może zaproponować lepszą metodę?

+1

Dlaczego nie używałbyś tylko metody File.Copy()? –

+0

Jakie są Twoje wymagania? Robocopy ma wiele funkcji (wielowątkowość, wznawianie, ponawianie itd.), Które Cię interesują? – RedFilter

+0

Czy istnieje szczególny powód, dla którego używasz RoboCopy? – Marco

Odpowiedz

3

Po prostu użyłbym System.IO. Powinny być wystarczająco szybkie, a nazwa pliku może być symbolem wieloznacznym.

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 
} 
+4

File.Copy jest naprawdę powolny w porównaniu do ROBOCOPY. Dobrze? –

+0

Prawdopodobnie nie zastanawia się, w jaki sposób postawiono oryginalne pytanie. Łamanie procesu i oczekiwanie na niego jest prawdopodobnie wolniejsze ogólnie. Biorąc pod uwagę niektóre inne komentarze, warto rozważyć zrobienie pliku File.Copy, ale bądź kreatywny w sposobie odpalania procesu kopiowania. Można rozważyć użycie osobnego wątku do kopiowania bez nadzoru. –

+3

Twoja odpowiedź nie jest przydatna, ponieważ File.copy nie ma wszystkich funkcji robocopy. na przykład: Obsługa Longpath – Honorificabilitudinitas

2

Powinieneś zadzwonić pod numer File.Copy w pętli.

+0

A jeśli nie chce zablokować głównego wątku, mógłby wykonać tę pracę w osobnym wątku (może BackgroundWorker'), który powiadamia UI ... – Marco

0

cmd ma następujące linie

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 

Kiedy biegnę> Robocopy sample.cmd I zaczyna się od 4 wielu okien kopiowanie plików jednocześnie, jak na powyższych poleceń, to czeka do innego pliku, jak ma czas oczekiwania, jeśli plik jest używany przez inny proces. Jest więcej szybsze, niż wykonywanie pracy jednocześnie.

Teraz Zajmuję GUI za pomocą C# Windows, aby uruchomić proces zamiast zamierza dowodzić konsoli i
rozpoczęcia

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

Jeśli jednak przejmuje kontrolę nad jednym procesie, czyli cmd.exe i i istnieje 4 procesy robocopy w menedżerze zadań . po zakończeniu procesu cmd.exe, zwraca kursor do etykiety.tekst "Zakończono pomyślnie". Chociaż nadal istnieją procesy robocopy. możesz zobaczyć robocopy windows podczas kopiowania.

Oto pytanie: Chcę, by przejąć kontrolę nad wszystkimi procesami (cmd.exe i robocopy.exe) programowo w C#, tak, że gdy label.text powinien wyświetlać „pomyślnie” tylko gdy wszystkie polecenia Pomyślnie zakończono ", jeśli się nie powiedzie, nie ma sensu w GUI:

opcja 2 (podobna do Biju napisał powyżej): czy lepiej jest usunąć skrypty poleceń robocopy z sample.cmd (plik wsadowy) plik i napisać kod, aby uruchomić 4 linie robocopy w języku C#, ale jak uruchomić skrypt roboczy napisany plik .cmd, ponieważ mają one również argumenty.Zapytam kod każdego procesu robocopy następnie każdy powróci do następnej linii kodu, a jeśli się nie powiedzie, możemy uchwycić błąd i wyświetlić komunikat w oknie komunikatu.

Mam nadzieję, że to pomoże ... Jednak szukam lepszego sposobu, jeśli ktoś może poprawić to samo.

+1

@ user2045570 Dlaczego nie usunąłeś pustych linii, gdy jesteś na tym? –

+0

@ TobiasKienzler musiał tego nie zauważyć. Będę uważać na puste linie następnym razem. – nedaRM

9

To pytanie jest nieco stare, ale myślałem, że odpowiem, aby pomóc każdemu, kto nadal na nim ląduje. Napisałem bibliotekę o nazwie RoboSharp (https://github.com/tjscience/RoboSharp), która przenosi cały dobro w Robocopy na C#. Spójrz, jeśli potrzebujesz mocy Robocopy w języku C#.

+1

Awesome! Czy wszystko, czego szukałem! – NielW

0
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 
Powiązane problemy