Hmm, je crois que j'ai mal compris la question mais je vais m'y risquer. Quel est le problème avec la méthode simple suivante ?
public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) {
foreach (DirectoryInfo dir in source.GetDirectories())
CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
foreach (FileInfo file in source.GetFiles())
file.CopyTo(Path.Combine(target.FullName, file.Name));
}
EDIT Puisque ce message a recueilli un nombre impressionnant de votes négatifs pour une réponse aussi simple à une question tout aussi simple, permettez-moi d'ajouter une explication. S'il vous plaît Lisez ceci avant de voter à la baisse .
Tout d'abord, Ce code n'est pas destiné à être remplacé par un autre code. au code de la question. Il s'agit uniquement d'une illustration.
Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory
effectue quelques tests d'exactitude supplémentaires (par exemple, si la source et la cible sont des répertoires valides, si la source est un parent de la cible, etc.) qui sont absents de cette réponse. Ce code est probablement aussi plus optimisé.
Cela dit, le code fonctionne bien . Il s'agit de a (presque identique) est utilisé dans un logiciel mature depuis des années. En dehors de l'inconstance inhérente à toute gestion des entrées/sorties (par exemple, que se passe-t-il si l'utilisateur débranche manuellement la clé USB alors que votre code est en train d'écrire dessus ?
En particulier, j'aimerais souligner que l'utilisation de la récursion ici n'est absolument pas un problème. Ni en théorie (conceptuellement, c'est la solution la plus élégante), ni en pratique : ce code ne débordera pas de la pile . La pile est suffisamment grande pour gérer même les hiérarchies de fichiers profondément imbriquées. Bien avant que l'espace de la pile ne devienne un problème, la limitation de la longueur du chemin du dossier entre en jeu.
Notez qu'un utilisateur malveillant Il est possible de briser cette hypothèse en utilisant des répertoires profondément imbriqués d'une lettre chacun. Je n'ai pas essayé. Mais juste pour illustrer le point : afin de faire déborder ce code sur un ordinateur typique, les répertoires devraient être imbriqués plusieurs fois. mille temps. Ce n'est tout simplement pas un scénario réaliste.
0 votes
Copier un répertoire et son contenu dans un autre répertoire en C# .
108 votes
Je dirais qu'en regardant les alternatives postées ci-dessous, la méthode VB n'est pas si moche.
2 votes
La vraie question est de savoir pourquoi cela ne fait pas partie de la bibliothèque IO par défaut. À l'heure actuelle, nous avons probablement tous mis le même code dans notre bibliothèque personnelle.
44 votes
Comment cela peut-il être un hack alors que cela fait partie du .NET Framework ? Arrêtez d'écrire du code et utilisez ce que vous avez.
1 votes
Microsoft.VisualBasic
est un ensemble de modules complémentaires destinés à faciliter la mise à jour des projets VB6 existants. Vous ne l'utiliseriez normalement pas dans une application C#. S'il s'agissait d'un élément "propre" du cadre .Net, il se trouverait dans le module de gestion de l'environnement.System.IO
. Aussi, seul leSystem.[something]
Les espaces de noms font partie de Mono.15 votes
C'est une idée fausse et courante. Microsft.VisualBasic contient toutes les procédures Visual Basic courantes qui rendent le codage en VB tellement plus facile. Microsot.VisualBasic.Compatibility est l'assemblage utilisé pour l'héritage de VB6.
1 votes
Si vous regardez la source de CopyDirectory, vous verrez qu'il utilise System.IO ou des appels internes de l'API Shell, selon la façon dont CopyDirectory est appelé.
0 votes
La raison pour laquelle Microsoft.VisualBasic n'est pas ajouté à un projet C# est qu'il ne s'agit pas d'un projet VB. Même les projets VB.NET doivent ajouter Microsoft.VisualBasic.Compatibility s'ils veulent utiliser les anciennes fonctionnalités. La couche de compatibilité n'est ajoutée que par l'assistant de migration ou par l'utilisateur.
65 votes
Il y a plus de 2 000 lignes de code dans Microsoft.VisualBasic.Devices.Computer.FileSystem. CopyDirectory garantit que vous ne copiez pas un dossier parent dans un dossier enfant et d'autres vérifications. Il est hautement optimisé, et ainsi de suite. La réponse choisie est au mieux un code fragile.
1 votes
C'est une limitation de Mono. Cela ne fait pas partie de votre réponse. Vous voulez une meilleure solution et il n'y en a pas.
6 votes
Si vous avez besoin de System.Windows.Forms.Design, allez-vous éviter d'ajouter cette référence simplement parce qu'elle comporte les mots "Design" ? Bien sûr que non. Par conséquent, éviter quelque chose qui est intégré dans le framework juste parce qu'il y a le mot "VisualBasic" dans son nom est, eh bien..., tout simplement... stupide.
8 votes
Les gars de C# me tuent. Il ne s'agit pas d'outils, mais de solutions.
18 votes
@AMissico - ok, alors pourquoi ce code optimisé et complet est en
Microsoft.VisualBasic
et nonSystem.IO
? La raison pour laquelle il n'est pas dans Mono est que toutes les bibliothèques qui sont considérées comme "de base" sontSystem.[something]
- toutes les autres ne le sont pas. Je n'ai aucun problème à référencer une DLL supplémentaire, mais il y a une bonne raison pour laquelle Microsoft n'a pas inclus cette fonctionnalité dans le logicielSystem.IO
.4 votes
A tous ceux qui pensent que c'est bien d'utiliser
Microsoft.VisualBasic
: seriez-vous heureux d'utiliser une bibliothèque de Perl en python ? C'est en gros ce qui se passe, avec des différences mineures. De plus, en n'utilisant pasSystem.*
les bibliothèques, ils sont potentiellement contraints d'utiliser Mono, ce qui, d'après les commentaires de l'OP, peut être un problème.13 votes
@RCIX : Les meilleurs développeurs sont ceux qui accomplissent le travail efficacement et rapidement. Alors que faire si le nom a Visual Basic, le fait est que le code dans la DLL est simplement MSIL. Microsoft a clairement écrit un algorithme efficace et il serait dommage pour quelqu'un de le négliger juste parce qu'il a le mot Visual Basic dans son nom. D'autant plus si l'algorithme qu'il écrit juste à cause d'une bizarrerie dans le nom de la DLL finit par être bogué et coûte plus de temps à réparer.
1 votes
@Keith : Peut-être que la BCL a été finalisée avant qu'ils ne découvrent que cette fonction était nécessaire. Tout ce que nous pouvons faire est de spéculer à ce stade. Avez-vous une bonne raison de ne pas inclure la DLL, à part son nom ? La documentation MSDN indique-t-elle que cette fonction est dépréciée ?
4 votes
@jasonh : nah - c'est une question assez ancienne maintenant et la référence Microsoft.VisualBasic est dans les logiciels livrés depuis plus d'un an. Je me demandais juste pourquoi elle se trouvait à cet endroit étrange - elle devrait être quelque chose comme
System.IO.Directory.Copy(sourceFolder, outputFolder)
1 votes
Je suis d'accord pour dire que c'est là qu'elle devrait être, mais il est tout à fait plausible que la BCL ait été finalisée avant qu'ils ne réalisent qu'elle serait nécessaire pour VB et donc, son utilité, et qu'ils n'aient jamais pensé à la revoir. C'est juste une hypothèse :)
0 votes
Je viens de faire un Q&A avec des options de type xcopy en C#. stackoverflow.com/questions/22151995/
1 votes
J'utilise robocopy, ça marche très bien
0 votes
Notez que
Microsoft.VisualBasic.Devices
n'est pas disponible dans .NET core : github.com/dotnet/docs/issues/145461 votes
Utilisation de ce code en production pour copier des répertoires et des fichiers imbriqués. Je n'ai pas trouvé de problème. docs.microsoft.com/fr/us/dotnet/standard/io/