2016-01-28 2 views
4

Вот мой код, который я использую, чтобы извлечь почтовый файл убедившись, что целевая папка не имеет каких-либо грязных файлов в немПочему иногда Directory.CreateDirectory не работает?

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

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

Иногда Directory.CreateDirectory(SourceDir) не удается создать новый каталог и я получаю исключение на следующей строке но если я отступлю и повторю попытку создания dir, это сработает. Точно такая же картина повторяется при следующем выполнении.

EDIT
Вот исключение, которое на самом деле о реж что не был создан, я могу видеть ЦСИ папка не существует:

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

Что такое исключение, которое вы получите * «иногда» * – Habib

+0

Как часто вы запускаете этот метод? Один раз в час, раз в минуту, 1000 раз в секунду? – Oxoron

+0

Выполнение этого метода, только при запуске приложения. В производстве это можно вспомнить раз в несколько минут – WSK

ответ

2

Спасибо, что помогли мне решить эту проблему. Проблема заключалась в создании каталога сразу после вызова его удаления. В моем случае удаленный каталог был пуст, но, вероятно, из-за задержек файловой системы, он стал недоступным до полного удаления. Я делюсь решение, для других, стоящих перед такой же вопрос:

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

Ошибка на самом деле в исключение уже.

System.UnauthorizedAccessException was unhandled 

Необходимо добавить коды, чтобы проверить/подтвердить, что пользователь имеет доступ к папке.

+0

Не должно быть доступа, так как оно работает при повторном запуске. Кроме того, как я могу проверить доступ, когда src dir вообще не существует во время исключения? – WSK

+0

Ваша логика повторения не будет иметь к этому никакого отношения. С доступом @Batuta скорее означает разрешения –

+0

Извините за путаницу. Говоря «повторить попытку», я решил снова отступить в отладчике и снова выполнить эту строку кода, в том же запуске приложения. – WSK

0

Мой коллега получил эту ошибку при частом переписывании файлов. Он сказал, что система Fyle медленная. Если у вас такая же проблема, вы пытаетесь создать папку, которая еще не удалена.

Попробуйте повторить ваш метод один раз на UnauthorizedAccessException или \ и добавить Thread.Sleep (100) после Directory.Delete.

+0

В моем случае каталог никогда не существует, поэтому его нельзя удалить. – WSK

0

Я сам испытал это поведение. Если я не ошибаюсь, это происходит потому, что Directory.Delete все еще работает, пытаясь удалить каталог, в то время как Directory.CreateDirectory пытается его воссоздать. Ошибка CreateDirectory завершится неудачей, поскольку в системе этот ресурс все еще заблокирован для удаления.

Я избегал этой проблемы, введя небольшую задержку между вызовом Delete и вызовом CreateDirectory. Другой вариант, который я помню, заключался в том, чтобы переименовать каталог, а затем удалить его. Например, если исходный каталог был вызван MyApp, я бы переименовал его в DeleteMe, а затем удалю этот каталог. CreateDirectory должен иметь возможность создавать каталог MyApp, поскольку этого больше не существует.

8

Если бы эту проблему под Windows 7, .Net 4.0, VS2010. Казалось бы, Directory.Delete() не является синхронным, поэтому проблема связана с синхронизацией. Я предполагаю, что Directory.CreateDirectory() не сработает, потому что существующая папка помечена для удаления. Новая папка затем отбрасывается как «Directory.Delete()).

Я нашел это работает последовательно:

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

Directory.CreateDirectory(myPath);