Système.IO.DirectoryNotFoundException après la suppression d'un dossier vide et le recréer
Je veux copier un dossier, et je veux supprimer le dossier de destination première.
Donc, je suis à la suppression de dossier de destination puis de le recréer et puis copier les fichiers.
Le problème est que je reçois le An unhandled exception of type 'System.IO.DirectoryNotFoundException' occurred in mscorlib.dll
lorsque vous essayez de copier des fichiers. C'est le code
static public void CopyFolder(string sourceFolder, string destFolder)
{
if (Directory.Exists(destFolder)) //check if folde exist
{
Directory.Delete(destFolder, true); //delete folder
}
Directory.CreateDirectory(destFolder); //create folder
string[] files = Directory.GetFiles(sourceFolder);
foreach (string file in files)
{
string name = Path.GetFileName(file);
string dest = Path.Combine(destFolder, name);
File.Copy(file, dest, true);
FileInfo fileinfo = new FileInfo(dest); //get file attrib
if (fileinfo.Attributes != FileAttributes.ReadOnly) //check if read only
File.SetAttributes(dest, FileAttributes.Normal);
}.......
- Je obtenir de l'exception dans cette ligne FileInfo fileinfo = new FileInfo(dest);
.
Il semble que il ya un retard dans la création du dossier et dans le temps, j'essaye de copier un fichier. Aucune idée, quel est le problème? Le plein de message d'exception:
Une exception non gérée du type
'Système.IO.DirectoryNotFoundException'
s'est produite dans mscorlib.dllInformations supplémentaires: impossible de trouver
une partie du chemin
'C:\Users\joe\Desktop\destfolder\.buildpath'.
SOLUTION
Comme il été souligné par les gens de bien, la raison de cette exception est que j'essaie de recréer le dossier avant le processus de suppression est terminé.
Donc la solution est d'ajouter 2 lignes de code après suppression:
GC.Collect();
GC.WaitForPendingFinalizers();
donc le bon code sera
static public void CopyFolder(string sourceFolder, string destFolder)
{
if (Directory.Exists(destFolder)) //check if folde exist
{
Directory.Delete(destFolder, true); //delete folder
GC.Collect(); //CODE ADDED
GC.WaitForPendingFinalizers(); //CODE ADDED
}
Directory.CreateDirectory(destFolder); //create folder
string[] files = Directory.GetFiles(sourceFolder);
foreach (string file in files)
{
string name = Path.GetFileName(file);
string dest = Path.Combine(destFolder, name);
File.Copy(file, dest, true);
FileInfo fileinfo = new FileInfo(dest); //get file attrib
if (fileinfo.Attributes != FileAttributes.ReadOnly) //check if read only
File.SetAttributes(dest, FileAttributes.Normal);
}.......
De cette façon, vous attendez avec la création jusqu'à ce que le processus de suppression est terminé.
Yhanks tout le monde et surtout Saeed.
Êtes-vous sûr que le fichier est copié? Je vous suggère un peu de débogage de code où vous la sortie de la source et de la destination des noms de fichiers avant de faire la copie, puis afficher un message qui dit, "Fichier copié" une fois la copie terminée. Il semble peu probable que la copie terminée avec succès, puis l'appel à
FileInfo
constructeur échouer.Lorsque vous déboguez ce, quelle est la valeur de
dest
sur la ligne qui lance l'exception? Quelles sont les valeurs des autres variables pertinentes?si le dossier de destination n'existe pas et je le lance ,il n'y a pas de problème. mais si le dossier existe et il est vide - puis-je obtenir de l'exception. dest = "C:\\Users\\.....\\Desktop\\destfolder\\.buildpath"
Quel est votre message d'exception? Je pense qu'il y a un problème de sécurité, d'offrir le plein de message d'exception
OriginalL'auteur yossi | 2010-11-18
Vous devez vous connecter pour publier un commentaire.
Vous l'ai eu un peu de mal. La raison de cette exception est qu'il y a encore une ressource qui est en train d'accéder au dossier (ou fichier).
La solution n'est jamais
GC.collect()
ouSleep()
... C'est juste un travail autour de.Ce que vous faites est tout simplement de laisser le garbage collector de disposer de la ressource, et de donner ensuite le temps d'agir.
La DROIT façon de gérer vos propres ressources. Au lieu d'une méthode statique que vous n'avez aucun contrôle sur, utiliser un
using
bloc et de disposer de la ressource à la fin du bloc. De cette façon, il n'y a pas de frais généraux, tandis que votre attente pour des choses qui ne sont pas sous votre contrôle (GC).Utiliser un objet qui contrôle les ressources, et la
using
bloc de la jeter à la fin.Dans votre cas, à l'aide d'un seul
DirectoryInfo
objet qui contrôle cette ressource devrait fonctionner.Mon erreur, DirectoryInfo n'est pas jetable. l'aide ne peut être utilisé sur Idisposable objets.
Je ne vois pas comment l'Utilisation de l'aideront dans mon cas. J'ai une arborescence de dossiers à partir d'un programme C#. Lorsque l'utilisateur quites la structure de l'arbre doit être détruit. Si il y a des fichiers à l'intérieur de cette structure, le rutines jette l'exeception, eventhough-je utiliser la FORCE suppression récursive sur les dossiers. Si j'utilise la GC.Recueillir et GC.waitforfinalizers méthode, je n'ai pas de problèmes. Comment dois-je convertir cette Aide? Rendre l'ensemble du programme d'une grande Aide?
Non, le fait que la gc.recueillir résout le problème, signifie qu'il y a des ressources qui ne sont pas éliminés correctement, et sont éliminés lorsque vous la force de leur collection. Ce que vous devez faire est de garder une trace des objets créés dans les coulisses, et les jeter.
si j'ai créer deux dossiers, et à partir de l'Explorateur manuellement, faites glisser un fichier dans le sous-dossier de la deux, je peut provoquer cette erreur. Quelle ressource serait-il que j'ai besoin de communiquer?
OriginalL'auteur
Je suis confus au sujet de votre solution actuelle. GC n'a rien à voir avec la suppression d'un dossier, il ne fonctionne que parce que l'ajout d'GC liées fonctionnalité est similaire à l'ajout de Fil.Sleep() ou une MessageBox. Il ne fonctionne que par hasard.
Au lieu de cela, vous devriez attendre jusqu'à ce que le répertoire est en fait supprimé.e.g:
Qu'une seule fois ce code se termine, vous devez continuer.
Il semble très étrange pour moi de compter sur l'intérieure de la mise en œuvre de Répertoire.Supprimer et même plus si vous le faites à l'aide de GC. Il n'y a aucune garantie que l'intérieur de la mise en œuvre ne va pas changer dans la prochaine .Version NET. Le moyen le plus sûr pour aller, à mes yeux, est celui qui apparaît dans ma réponse. Vérifiez également la discussion sur le sujet ici: social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/...
Il y a beaucoup de mal avec la question et le actuellement à la solution retenue. Ce doit être la accepté de répondre.
OriginalL'auteur
Essayez d'utiliser le FileIO méthode au lieu de cela, j'ai eu le même problème, le code ci-dessous fonctionne parfaitement.
FileIO.Système de fichiers.DeleteDirectory(directoryName,FileIO.DeleteDirectoryOption.DeleteAllContent)
J'ai eu ce problème, modifié à l'aide de la FileIO méthode et obtiens toujours la même erreur.
OriginalL'auteur
Pourquoi vous mettez-vous les attributs de fichier après avoir copié le fichier? Est-ce nécessaire?
Ce que vous pourriez faire est de définir au préalable les différents attributs et ensuite effectuer la copie de fichier. Il rend également plus de sens, en vérifiant d'abord si c'est un fichier En lecture seule, et si elle l'est, puis le mettre à la Normale, et faire la copie.
OriginalL'auteur
Désolé de répondre et de ne pas commenter, mais ma réputation n'est pas assez encore. Dans la MSDN est écrit, que le chemin d'accès doit être "bien formé" http://msdn.microsoft.com/en-gb/library/system.io.fileinfo%28v=VS.90%29.aspx
Peut-être en train de l'essayer, en mettant le fichier dans le répertoire de travail? Si aucun chemin d'accès n'est nécessaire et vous pouvez voir si le problème est dans le chemin d'accès ou au fichier...
OriginalL'auteur
Ok C'est très étrange.
la seule exception se produire lorsque le dossier de destination est vide.
mais l'ajout de ce qui suit après le dossier de destination de la suppression de résoudre le problème.
la ligne :
MessageBox.Afficher("dossier" + destFolder + "le dossier a été supprimé", "alerte");
donc en mettant une MessageBox.spectacle après la suppression entraîne le Système.IO.DirectoryNotFoundException de s'en aller. c'est comme si le fait qu'il y a un petit retard après la suppression , le loisir de le dossier va bien.
je pense que je vais trouver un travail autour de cela, mais si quelqu'un sait quelle en est la cause et le moyen de le résoudre , je serai très heureux de l'entendre.
OriginalL'auteur
Essayer de mettre Fileinfo de dest d'abord, puis copiez
Je pense que votre programme est optimisé de sorte lors de la suppression du dossier, puis de le recréer, le thread responsable de la copie est commencé avant la finition. Pourquoi ne pas vous apporter le code de création de répertoire à l'intérieur de l'instruction si, après le répertoire de suppression.
Je pense que vous avez raison à propos de la raison à l'origine de cette exception ,et saïd l'a déjà souligné la solution.maintenant, quant à la création d'un répertoire à l'intérieur de l'instruction si - que serait la réplication de code, car j'aurais besoin d'un autre sur l'instruction if dans le cas où le dossier n'existe pas.
OriginalL'auteur