Dienstag, 20. Juli 2010

Dateien / Ordner kopieren

In den vorigen Posts haben wir gesehen, wie man prüft, ob Dateien oder Ordner bereits existieren, wie man diese Elemente verschiebt und wie man alle Elemente in einem Ordner aufzählt.
Das Kopieren von Dateien ist ebenfalls mit einem Befehl erledigt:

System.IO.File.Copy("C:\\Quelldatei.txt", "C:\\Testordner\\Zieldatei.txt", true);

Die Pfade müssen vorhanden sein, beispielsweise führt das Fehlen des Ordners "Testordner" zu einer Exception.
Der 3. Parameter ist optional und gibt an, ob die Datei überschrieben werden soll, falls sie schon existiert (true bedeutet überschreiben, wird der Parameter nicht übergeben wird false angenommen).
Ironischerweise ist aber das Kopieren eines Ordners um einiges komplizierter als das Verschieben.
Das Verschieben eines Elements bedeutet einfach einen Eingriff in das Dateisystem, dem Computer wird lediglich mitgeteilt, dass sich der Pfad zum Element geändert hat.
Beim Kopieren muss die Datei oder der Ordner dupliziert werden, es muss also der Inhalt kopiert werden und das neu entstandene Element muss im Dateisystem "angemeldet" werden. Bei Ordnern führt das zu dem Problem, dass die komplette Ordnerhierarchie samt Unterordnern etc. nachgebildet werden muss - in C# gibt es hierfür keine eigene Funktion!
Deshalb werden wir hier jetzt eine basteln.
Die Funktion arbeitet rekursiv, sie ruft sich zuerst immer selbst mit allen Unterordnern auf und bildet so die Ordnerstrukturen nach. Dann werden alle Dateien im aktuellen Ordner kopiert (using System.IO; vorausgesetzt):

        private void CopyDirectory(string sourceDirectory, string destDirectory)
        {
            DirectoryInfo ds = new DirectoryInfo(sourceDirectory); // diese Klasse wird zum Auslesen des Verzeichnisinhaltes benötigt

            // Zielverzeichnis anlegen falls noch nicht vorhanden
            if (!Directory.Exists(destDirectory))
                Directory.CreateDirectory(destDirectory);

            // Rekursiv CoypDirectory() mit allen Unterverzeichnissen aufrufen,
            // auch im Zielordner die Verzeichnisstruktur beibehalten.
            foreach (DirectoryInfo d in ds.GetDirectories())
            {
                CopyDirectory(d.FullName, destDirectory + "\\" + d.Name);
            }

            // Alle Dateien in ds durchlaufen, GetFiles() liefert jedoch kein File - Objekt sondern ein FileInfo - Objekt zurück.
            // Dieses besitzt aber ähnliche Eigenschaften, MoveTo() und CopyTo() sind z.B. auch vorhanden.
            foreach (FileInfo f in ds.GetFiles())
            {
                f.CopyTo(destDirectory + "\\" + f.Name, true);
            }
        }

Ein Beispielaufruf könnte so aussehen:
CopyDirectory("C:\\Quellordner", "C:\\Zielordner");

Kommentare:

  1. genial, danke für den denkanstoss

    AntwortenLöschen
  2. gute Idee, hilft mir viel weiter

    AntwortenLöschen
  3. falls du hier noch aktiv bist. ist es möglich den fortschritt des kopierens in einer progress-bar wiederzugeben. wenn ja wie?

    AntwortenLöschen