2013-05-02 2 views
0

У меня есть следующий код C# для вычисления хэша каждого файла в определенном, указанном пользователем каталоге. Дело в том, что он отлично работает, пока не встретит файл, к которому он не может получить доступ. Когда он находит что-то вроде этого, он просто выдает сообщение об ошибке и выходит из программы. Вместо этого я хочу, чтобы это сообщение вызывало ошибку с именем файла, к которому нельзя получить доступ, напишите, что есть ошибка при доступе к этому файлу, и продолжайте выполнение программы с другими файлами в каталоге. Если кто-то может помочь мне изменить мой код и достичь тех вещей, я был бы рад.Попробуйте, оператор catch в C#

private void SHA256Directory(string directory) 
    { 
     try 
     { 
      SHA256 DirectorySHA256 = SHA256Managed.Create(); 
      byte[] hashValue; 

      DirectoryInfo dir = new DirectoryInfo(directory); 
      FileInfo[] files = dir.GetFiles(); 

      foreach (FileInfo fInfo in files) 
      { 
       FileStream fStream = fInfo.Open(FileMode.Open); 
       fStream.Position = 0; 
       hashValue = DirectorySHA256.ComputeHash(fStream); 

       Console.WriteLine(fInfo.Name); 
       Miscellaneous.ByteArrayToHex(hashValue); 
       Miscellaneous.ByteArrayToBase64(hashValue); 
       Console.WriteLine(); 

       fStream.Close(); 
      } 

      return; 
     } 
     catch(DirectoryNotFoundException) 
     { 
      Console.WriteLine("Error: The directory specified could not be found."); 
     } 
     catch(IOException) 
     { 
      Console.WriteLine("Error: A file in the directory could not be accessed."); 
     } 
     catch(ArgumentNullException) 
     { 
      Console.WriteLine("Error: The argument cannot be null or empty."); 
     } 

    } 

ответ

8

Перемещайте TRY/поймать внутри foreach. Вы не объяснили в своем посте, но я предполагаю, что вы столкнулись с исключением.

При этом любое исключение, вызванное кодом, будет обнаружено и разрешить цикл.

Осторожно, хотя - эти две линии по-прежнему не является исключением безопасной:

DirectoryInfo dir = new DirectoryInfo(directory); 
FileInfo[] files = dir.GetFiles(); 

Вы хотите, чтобы объяснить, что хорошо.

Если вы хотите, чтобы показать, что именно то, что файл/каталог вызвал вопрос, просто toString исключение, например:

catch(DirectoryNotFoundException ex) 
{ 
    Console.WriteLine("Error: The directory specified could not be found: " + ex.toString()); 
} 

Если toString не дает желаемых результатов, попробуйте ex.Message. Я всегда просто использую toString.

EDIT кредит Ken Henderson

При использовании любого рода Stream, вы должны поместить его в using блоке. Сборщик мусора будет Close поток в конце концов, но это хорошая практика, чтобы сделать это, как using блок будет закрыть поток, как только вы закончите его использования:

using (FileStream fStream = fInfo.Open(FileMode.Open)) 
{ 
    fStream.Position = 0; 
    hashValue = DirectorySHA256.ComputeHash(fStream); 

    Console.WriteLine(fInfo.Name); 
    Miscellaneous.ByteArrayToHex(hashValue); 
    Miscellaneous.ByteArrayToBase64(hashValue); 
    Console.WriteLine(); 
} // No need for fStream.Close() any more, the using block will take care of it for you 
+4

не думает, что это заслуживает другого ответа, но не забывайте, что вы должны либо иметь, используя заявление при открытии потока или, наконец, блока для попытки улова блоков, чтобы обеспечить поток закрыт/удалено –

+0

Хорошо, добавлено ж/кредит вам – tnw

1

Scope является ключевым словом здесь.

Ваша попытка захвата окружает весь foreach. Это означает, что при возникновении ошибки он выйдет из режима foreach. Вы хотите, чтобы try-catch приблизился к месту происхождения (fInfo.Open(FileMode.Open)). Таким образом, после ошибки он может просто продолжить обработку цикла.

1

Попробуйте вместо этого:

private void SHA256Directory(string directory) 
{ 
    SHA256 DirectorySHA256 = SHA256Managed.Create(); 
    byte[] hashValue; 

    DirectoryInfo dir = new DirectoryInfo(directory); 
    FileInfo[] files = dir.GetFiles(); 

    foreach (FileInfo fInfo in files) 
    { 
     try 
     { 
      FileStream fStream = fInfo.Open(FileMode.Open); 
      fStream.Position = 0; 
      hashValue = DirectorySHA256.ComputeHash(fStream); 

      Console.WriteLine(fInfo.Name); 
      Miscellaneous.ByteArrayToHex(hashValue); 
      Miscellaneous.ByteArrayToBase64(hashValue); 
      Console.WriteLine(); 

      fStream.Close(); 
     } 
     catch(DirectoryNotFoundException) 
     { 
      Console.WriteLine("Error: The directory specified could not be found."); 
     } 
     catch(IOException) 
     { 
      Console.WriteLine("Error: A file in the directory could not be accessed."); 
     } 
     catch(ArgumentNullException) 
     { 
      Console.WriteLine("Error: The argument cannot be null or empty."); 
     } 
    } 
    return; 
} 


} 
+0

Ну, в 'dir.GetFiles 'могут быть исключения, которые вы сейчас не ловите. –

+0

Это правда. Я предполагал, что он больше беспокоился об обработке ошибок, когда он не мог получить доступ к файлам. По этой причине я бы выбрал ваше решение по моему. – gwin003

+0

положить внутреннюю попытку/уловку (предназначенную для улавливания ошибки из файла открытия), вокруг только файла.open –

2

Вы должны реорганизовать свой код так:

private void SHA256Directory(string directory) 
{ 
    try 
    { 
     DirectoryInfo dir = new DirectoryInfo(directory); 
     FileInfo[] files = dir.GetFiles(); 

     foreach (FileInfo fInfo in files) 
     { 
      try 
      { 
       SHA256 DirectorySHA256 = SHA256Managed.Create(); 
       byte[] hashValue; 

       FileStream fStream = fInfo.Open(FileMode.Open); 
       fStream.Position = 0; 
       hashValue = DirectorySHA256.ComputeHash(fStream); 

       Console.WriteLine(fInfo.Name); 
       Miscellaneous.ByteArrayToHex(hashValue); 
       Miscellaneous.ByteArrayToBase64(hashValue); 
       Console.WriteLine(); 

       fStream.Close(); 
      } 
      catch (...) 
      { 
       // Handle other exceptions here. Through finfo, you can 
       // access the file name 
      } 
     } 
    } 
    catch (...) 
    { 
     // Handle directory/file iteration exceptions here 
    } 
} 
0

Вы также должны обрабатывать UnauthorizedAccessException которого выкинули, если файл не доступен.

+0

Должен быть комментарий – spender

0

Возможно, я что-то наблюдаю, потому что решение довольно простое, но;

Поместите блок Try-Catch, в котором рассматриваются проблемы с доступом внутри каждого из них - в случае, если один файл недоступен, исключение бросается, фиксируется, и после печати сообщения об ошибке продолжение foreach продолжается со следующего файла в список.

private void SHA256Directory(string directory) 
{ 
    try 
    { 
     SHA256 DirectorySHA256 = SHA256Managed.Create(); 
     byte[] hashValue; 

     DirectoryInfo dir = new DirectoryInfo(directory); 
     FileInfo[] files = dir.GetFiles(); 

     foreach (FileInfo fInfo in files) 
     { 
      try 
      { 


       FileStream fStream = fInfo.Open(FileMode.Open); 
       fStream.Position = 0; 
       hashValue = DirectorySHA256.ComputeHash(fStream); 

       Console.WriteLine(fInfo.Name); 
       Miscellaneous.ByteArrayToHex(hashValue); 
       Miscellaneous.ByteArrayToBase64(hashValue); 
       Console.WriteLine(); 

       fStream.Close(); 
      } 
      catch(IOException) 
      { 
       Console.WriteLine("Error: A file in the directory could not be accessed."); 
      } 
     } 

     return; 
    } 
    catch(DirectoryNotFoundException) 
    { 
     Console.WriteLine("Error: The directory specified could not be found."); 
    } 
    catch(ArgumentNullException) 
    { 
     Console.WriteLine("Error: The argument cannot be null or empty."); 
    } 

} 
0

Чтобы узнать, какой файл не доступен, вы можете использовать следующий фрагмент кода:

catch(FileNotFoundException ex) 
{ 
Console.writeLine("File not found " + ex.FileName); 
} 
0

ручки UnauthorizedAccessException и поставить попробовать заявление в Еогеасп заявлении.

private void SHA256Directory(string directory) 
    { 
     SHA256 DirectorySHA256 = SHA256Managed.Create(); 
     byte[] hashValue; 

     DirectoryInfo dir = new DirectoryInfo(directory); 
     FileInfo[] files = dir.GetFiles(); 

     foreach (FileInfo fInfo in files) 
     { 
      try 
      { 
       FileStream fStream = fInfo.Open(FileMode.Open); 
       fStream.Position = 0; 
       hashValue = DirectorySHA256.ComputeHash(fStream); 

       Console.WriteLine(fInfo.Name); 
       Miscellaneous.ByteArrayToHex(hashValue); 
       Miscellaneous.ByteArrayToBase64(hashValue); 
       Console.WriteLine(); 

       fStream.Close(); 
      } 
      catch (DirectoryNotFoundException) 
      { 
       Console.WriteLine("Error: The directory specified could not be found."); 
      } 
      catch (UnauthorizedAccessException) 
      { 
       Console.WriteLine("Error: A file in the directory could not be accessed.in {0}", fInfo.Name); 
      } 
      catch (ArgumentNullException) 
      { 
       Console.WriteLine("Error: The argument cannot be null or empty."); 
      } 
      catch (IOException) 
      { 
       Console.WriteLine("Error:IOExcepiton occured"); 
      } 

     } 

     return; 
    } 
Смежные вопросы