Ich möchte den gesamten Inhalt eines Verzeichnisses in C # von einem Speicherort an einen anderen kopieren.
Es scheint keine Möglichkeit zu geben, dies mit System.IO
Klassen ohne viel Rekursion zu tun .
In VB gibt es eine Methode, die wir verwenden können, wenn wir einen Verweis auf Folgendes hinzufügen Microsoft.VisualBasic
:
new Microsoft.VisualBasic.Devices.Computer().
FileSystem.CopyDirectory( sourceFolder, outputFolder );
Dies scheint ein ziemlich hässlicher Hack zu sein. Gibt es einen besseren Weg?
Microsoft.VisualBasic
und nichtSystem.IO
? Der Grund, warum es nicht in Mono ist, ist, dass alle Bibliotheken, die als "Kern" betrachtet werden, sindSystem.[something]
- alle anderen nicht. Ich habe kein Problem damit, auf eine zusätzliche DLL zu verweisen, aber es gibt einen guten Grund, warum Microsoft diese Funktion nicht aufgenommen hatSystem.IO
.Antworten:
Viel einfacher
quelle
Replace
hat ein Problem, wenn Sie ein sich wiederholendes Muster innerhalb des Pfades haben, sollte zum Beispiel"sourceDir/things/sourceDir/things"
werden"destinationDir/things/sourceDir/things"
, aber wenn Sie ersetzen verwenden, wird es"destinationDir/things/destinationDir/things"
*.*
statt*
? Möchten Sie keine Dateien auch ohne Erweiterungen kopieren?Hmm, ich glaube, ich verstehe die Frage falsch, aber ich werde es riskieren. Was ist falsch an der folgenden einfachen Methode?
BEARBEITEN Da dieser Beitrag eine beeindruckende Anzahl von Abstimmungen für eine so einfache Antwort auf eine ebenso einfache Frage erhalten hat, möchte ich eine Erklärung hinzufügen. Bitte lesen Sie dies vor dem Downvoting .
Erstens ist dieser Code nicht als Ersatz für den betreffenden Code gedacht. Es dient nur zu Illustrationszwecken.
Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory
führt einige zusätzliche Korrektheitstests durch (z. B. ob Quelle und Ziel gültige Verzeichnisse sind, ob die Quelle ein übergeordnetes Element des Ziels ist usw.), die in dieser Antwort fehlen. Dieser Code ist wahrscheinlich auch optimierter.Das heißt, der Code funktioniert gut . Es wird (fast identisch) seit Jahren in einer ausgereiften Software verwendet. Abgesehen von der inhärenten Unbeständigkeit, die bei allen E / A-Handlings auftritt (z. B. was passiert, wenn der Benutzer das USB-Laufwerk manuell aussteckt, während Ihr Code darauf schreibt?), Sind keine Probleme bekannt.
Insbesondere möchte ich darauf hinweisen, dass die Verwendung der Rekursion hier absolut kein Problem darstellt. Weder theoretisch (konzeptionell ist es die eleganteste Lösung) noch in der Praxis: Dieser Code wird den Stapel nicht überlaufen . Der Stapel ist groß genug, um auch tief verschachtelte Dateihierarchien zu verarbeiten. Lange bevor der Stapelspeicherplatz zum Problem wird, tritt die Begrenzung der Ordnerpfadlänge in Kraft.
Beachten Sie, dass ein böswilliger Benutzer diese Annahme möglicherweise durch die Verwendung tief verschachtelter Verzeichnisse mit jeweils einem Buchstaben brechen kann. Ich habe das nicht versucht. Aber nur um den Punkt zu veranschaulichen: Um diesen Code auf einem typischen Computer überlaufen zu lassen, müssten die Verzeichnisse einige tausend Mal verschachtelt werden . Dies ist einfach kein realistisches Szenario.
quelle
Von MSDN kopiert :
quelle
Versuche dies:
Ihre xcopy-Argumente können variieren, aber Sie haben die Idee.
quelle
Wenn Sie den harten Weg gehen möchten, fügen Sie einen Verweis auf Ihr Projekt für Microsoft.VisualBasic hinzu und verwenden Sie dann Folgendes:
Die Verwendung einer der rekursiven Funktionen ist jedoch ein besserer Weg, da die VB-DLL nicht geladen werden muss.
quelle
System.IO.Directory
, aber es ist besser, als es neu zu schreiben!Diese Seite hat mir immer sehr geholfen, und jetzt bin ich an der Reihe, den anderen mit dem zu helfen, was ich weiß.
Ich hoffe, dass mein Code unten für jemanden nützlich ist.
quelle
Path.Combine()
. Verwenden Sie niemals die Verkettung von Zeichenfolgen, um Dateipfade zusammenzustellen.source_dir.Length + 1
, nichtsource_dir.Length
.Kopieren Sie den Ordner rekursiv ohne Rekursion, um einen Stapelüberlauf zu vermeiden.
quelle
Hier ist eine Dienstprogrammklasse, die ich für solche E / A-Aufgaben verwendet habe.
quelle
Es ist möglicherweise nicht leistungsbewusst, aber ich verwende es für 30-MB-Ordner und es funktioniert einwandfrei. Außerdem gefiel mir nicht die gesamte Menge an Code und Rekursion, die für eine so einfache Aufgabe erforderlich war.
Hinweis: ZipFile ist unter .NET 4.5+ im System.IO.Compression-Namespace verfügbar
quelle
Eine geringfügige Verbesserung der Antwort von d4nt, da Sie wahrscheinlich nach Fehlern suchen und die xcopy-Pfade nicht ändern müssen, wenn Sie auf einem Server und einem Entwicklungscomputer arbeiten:
quelle
Dies ist mein Code, hoffe diese Hilfe
quelle
SearchOption
Flag bei der Suche nach Ordnern und Dateien verwenden. Dies geschieht in 4 Codezeilen. Überprüfen Sie auch die.HasFlag
Erweiterung jetzt auf Aufzählungen.Wenn Sie Konrads beliebte Antwort mögen, aber möchten, dass das
source
selbst ein Ordner isttarget
, anstatt seine untergeordneten Elemente unter dentarget
Ordner zu legen, finden Sie hier den Code dafür. Es gibt das neu erstellte zurückDirectoryInfo
, was praktisch ist:quelle
Sie können jederzeit nutzen diese , von Microsofts Website genommen.
quelle
file.CopyTo(temppath, false);
"Kopieren Sie diese Datei an diesen Ort, nur wenn sie nicht vorhanden ist" steht, was meistens nicht das ist, was wir wollen. Aber ich kann verstehen, warum es standardmäßig so ist. Fügen Sie der Methode zum Überschreiben von Dateien möglicherweise ein Flag hinzu.tboswell ersetzt die Proof-Version (die gegenüber wiederholten Mustern im Dateipfad unempfindlich ist)
quelle
Path.Combine()
. Verwenden Sie niemals die Verkettung von Zeichenfolgen, um Dateipfade zusammenzustellen.Meine Lösung ist im Grunde eine Modifikation der Antwort von @ Termininja, aber ich habe sie ein wenig verbessert und sie scheint mehr als fünfmal schneller zu sein als die akzeptierte Antwort.
BEARBEITEN: Das Ändern von @Ahmed Sabry auf vollständig parallele foreach führt zu einem besseren Ergebnis. Der Code verwendet jedoch eine rekursive Funktion und ist in bestimmten Situationen nicht ideal.
quelle
Entschuldigung für den vorherigen Code, er hatte immer noch Fehler :( (fiel dem schnellsten Waffenproblem zum Opfer). Hier wird er getestet und funktioniert. Der Schlüssel ist SearchOption.AllDirectories, wodurch die Notwendigkeit einer expliziten Rekursion entfällt.
quelle
Hier ist eine Erweiterungsmethode für DirectoryInfo a la FileInfo.CopyTo (beachten Sie den
overwrite
Parameter):quelle
Verwenden Sie diese Klasse.
quelle
.ToList().ForEach(
(was etwas mehr Arbeit, Speicher und etwas langsamer ist als nur die direkte Aufzählung der Verzeichnisse) und als Erweiterungsmethode. Die ausgewählte Antwort verwendetSearchOption.AllDirectories
und vermeidet Rekursion, daher würde ich empfehlen, zu diesem Modell zu wechseln. Auch Sie in der Regel nicht erforderlich , den Namen des Typs in Erweiterungsmethoden - ich es umbenennen würde ,CopyTo()
so dass es wurdesourceDir.CopyTo(destination);
Eine Variante mit nur einer Schleife zum Kopieren aller Ordner und Dateien:
quelle
Regex
, sollten Sie dies wahrscheinlich auchRegex.Escape(path)
als Teil Ihrer Ausdruckskomposition verwenden (insbesondere unter Berücksichtigung des Windows-Pfadtrennzeichens). Sie können auch davon profitieren, einnew Regex()
Objekt außerhalb der Schleife zu erstellen (und möglicherweise zu kompilieren) , anstatt sich auf die statische Methode zu verlassen.Besser als jeder Code (Erweiterungsmethode zu DirectoryInfo mit Rekursion)
quelle
Kopieren und ersetzen Sie alle Dateien des Ordners
quelle
try
catch
throw
ist sinnlos.Der folgende Code ist ein Microsoft-Vorschlag zum Kopieren von Verzeichnissen und wird von lieber @iato geteilt, kopiert jedoch nur Unterverzeichnisse und Dateien des Quellordners rekursiv und kopiert den Quellordner nicht selbst (wie Rechtsklick -> Kopieren ).
Unter dieser Antwort gibt es jedoch einen schwierigen Weg :
wenn Sie kopieren möchten Inhalt der Quellordner und Unterordner rekursiv können Sie es einfach wie folgt verwenden:
Wenn Sie das Quellverzeichnis jedoch selbst kopieren möchten (ähnlich wie Sie mit der rechten Maustaste auf den Quellordner geklickt und dann auf Kopieren geklickt haben und dann im Zielordner auf Einfügen geklickt haben), sollten Sie Folgendes verwenden:
quelle