2016-01-28 2 views
4

Voici mon code que j'utilise pour extraire un fichier zip en vous assurant le répertoire cible n'a pas de fichiers sales dans cePourquoi parfois Directory.CreateDirectory échoue?

internal void UnzipProject() 
{ 
    if (Directory.Exists(SourceDir)) 
     Directory.Delete(SourceDir, true); 

    if (File.Exists(CodeZipFile)) 
    { 
     Directory.CreateDirectory(SourceDir); // fails here 
     ZipFile.ExtractToDirectory(CodeZipFile, SourceDir); 
    } 
} 

Quelque temps Directory.CreateDirectory(SourceDir) ne parvient pas à créer un nouveau répertoire et je reçois exception sur la même ligne mais si je recule et réessaye la création de dir, cela fonctionne. Exactement le même motif est répété lors de la prochaine exécution.

EDIT
est ici l'exception qui est en fait de ne pas avoir été dir créé, je peux voir le src dir n'existe pas:

System.UnauthorizedAccessException was unhandled 
    HResult=-2147024891 
    Message=Access to the path '(...MyPath...)\src\MySolution.sln' is denied. 
    Source=mscorlib 
    StackTrace: 
     at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
     at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 
     at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) 
     at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite) 
     at System.IO.Compression.ZipFileExtensions.ExtractToDirectory(ZipArchive source, String destinationDirectoryName) 
     at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName, Encoding entryNameEncoding) 
     at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName) 
........ 
+7

Quelle est l'exception que vous obtenez * « parfois » * – Habib

+0

À quelle fréquence avez-vous exécuter cette méthode? Une fois par heure, une fois par minute, 1000 fois par seconde? – Oxoron

+0

Exécution de cette méthode, au démarrage de l'application uniquement. En production il peut être rappelé une fois en plusieurs minutes – WSK

Répondre

2

Merci à tous pour m'avoir aidé à résoudre ce problème. Le problème était de créer un répertoire juste après avoir appelé sa suppression. Dans mon cas, le répertoire supprimé était vide mais probablement dû aux retards du système de fichiers, il est devenu inaccessible avant la suppression complète. Je partage la solution, pour d'autres face même question:

internal void UnzipProject() 
{ 
    if (Directory.Exists(SourceDir)) 
    { 
     DirectoryInfo di = new DirectoryInfo(SourceDir); 

     foreach (FileInfo file in di.GetFiles()) 
      file.Delete(); 

     foreach (DirectoryInfo dir in di.GetDirectories()) 
      dir.Delete(true); 
    } 

    if (File.Exists(zipFile)) 
     ZipFile.ExtractToDirectory(zipFile, SourceDir); 

    else 
    { 
     if (Directory.Exists(SourceDir)) 
      Directory.Delete(SourceDir, true); 
    } 
} 
4

L'erreur est en fait à l'exception déjà.

System.UnauthorizedAccessException was unhandled 

Vous devez ajouter des codes pour vérifier/vérifier que l'utilisateur a accès au dossier.

+0

Ne devrait pas être un problème d'accès, car il fonctionne sur réessayer. De plus, comment puis-je vérifier l'accès quand src dir n'existe pas du tout au moment de l'exception? – WSK

+0

Votre nouvelle tentative n'aura rien à voir avec cela. Avec l'accès @Batuta signifie plutôt les autorisations –

+0

Désolé pour la confusion. En disant "réessayer" je voulais revenir en arrière dans le débogueur et ré-exécuter cette ligne de code, dans la même exécution de l'application. – WSK

0

Mon collègue a eu cette erreur sur la réécriture fréquente des fichiers. Il a dit que Fyle System est lent. Si vous avez le même problème, vous essayez de créer un dossier qui n'est pas encore supprimé. Essayez de répéter votre méthode une fois sur UnauthorizedAccessException, ou \ et ajoutez Thread.Sleep (100) après Directory.Delete.

+0

Dans mon cas, le répertoire n'existe pas déjà pour ne pas être supprimé. – WSK

0

J'ai moi-même vécu ce comportement. Si je ne me trompe pas, cela arrive parce que Directory.Delete fonctionne toujours en essayant de supprimer le répertoire alors qu'en même temps Directory.CreateDirectory essaie de le recréer. Le CreateDirectory échouera, car le système a toujours cette ressource verrouillée pour la suppression.

J'ai évité ce problème en introduisant un léger délai entre l'appel à Delete et l'appel à CreateDirectory. Une autre option dont je me souviens avoir utilisé était de renommer le répertoire, puis de le supprimer. Par exemple, si le répertoire d'origine s'appelait MyApp, je le renommerais en DeleteMe, puis supprimerais ce répertoire. CreateDirectory devrait être capable de créer le répertoire MyApp, puisqu'il n'existe plus.

8

eu ce problème sous Windows 7, .Net 4.0, VS2010. Il semblerait Directory.Delete() n'est pas synchrone donc le problème est le timing. Je devine Directory.CreateDirectory() n'échoue pas parce que le dossier existant est marqué pour la suppression. Le nouveau dossier est ensuite supprimé en tant que Directory.Delete() se termine.

Je trouve cela fonctionne toujours:

if (Directory.Exists(myPath)) 
    { 
    Directory.Delete(myPath, true); 
    while (Directory.Exists(myPath)) 
    System.Threading.Thread.Sleep(10); 
    } 

Directory.CreateDirectory(myPath);