2013-05-27 3 views
6

Очевидно, что многим приложениям необходимо будет работать с файлами и отображать ошибки для пользователей. Однако члены класса System.IO.File выдают много исключений. Это только для ReadAllText:C# - эта хорошая практика для упрощения исключений, созданных System.IO.File.ReadAllText

  • ArgumentException
  • ArgumentNullException
  • PathTooLongException
  • DirectoryNotFoundException
  • IOException
  • UnauthorizedAccessException
  • FileNotFoundException
  • NotSupportedException
  • SecurityException

Так как поймать их и показывать их пользователю, а не глотать другие исключения?

Очевидно, что с совершенной кодирования вы можете устранить эти 2:

  • ArgumentException
  • ArgumentNullException

Если вы пишете (возможно болезненное) проверить можно устранить PathTooLongException. Но почему вы дублируете код для проверки того, что Microsoft написала?

Но другие исключения все еще может произойти, даже если вы сделали все проверки:

  • DirectoryNotFoundException
  • IOException
  • UnauthorizedAccessException
  • FileNotFoundException
  • NotSupportedException
  • SecurityException

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

Я не понимаю, что вы можете сделать в этих сценариях, за исключением отображения сообщения пользователя. Вы собираетесь найти каталог, который ОС не может найти? Исправить разрешения? Ввести код в ОС, чтобы поддерживать неподдерживаемую операцию? LOL Все, что я вижу, это показать сообщение об ошибке.

Так что, если мне нужно поймать все эти исключения каждый раз, когда я открываю файл для чтения текста, мой код должен быть длинным и повторяющимся, если только я не проглатываю исключения, перехватывая исключение.

Было бы хорошей практикой, чтобы создать исключение FileException и просто уловить все исключения, которые могут возникнуть при работе с файлами? То, что я имел в виду это:

public class FileException : Exception 
{ 
    public FileException(Exception e) 
     : base(e.Message, e.InnerException) 
    { 
    } 
} 

public static class FileNoBS 
{ 
    public static string ReadAllText2(string path) 
    { 
     try 
     { 
      return File.ReadAllText(path); 
     } 
     catch (ArgumentNullException e) 
     { 
      throw new FileException(e); 
     } 
     catch (ArgumentException e) 
     { 
      throw new FileException(e); 
     } 
     catch (PathTooLongException e) 
     { 
      throw new FileException(e); 
     } 
     catch (DirectoryNotFoundException e) 
     { 
      throw new FileException(e); 
     } 
     catch (FileNotFoundException e) 
     { 
      throw new FileException(e); 
     } 
     catch (IOException e) 
     { 
      throw new FileException(e); 
     } 
     catch (UnauthorizedAccessException e) 
     { 
      throw new FileException(e); 
     } 
     catch (NotSupportedException e) 
     { 
      throw new FileException(e); 
     } 
     catch (SecurityException e) 
     { 
      throw new FileException(e); 
     } 
    }  
} 

Тогда при ловле исключений я бы просто написать это:

 try 
     { 
      string text = FileNoBS.ReadAllText2(path); 
     } 
     catch (FileException e) 
     { 
      // display error to user 
     } 

Я не очень понимаю, почему Microsoft не группироваться все эти исключения Снегурочка каким-то образом. Я что-то упускаю или это хорошая практика?

+1

Но каков практический результат этого? Вы не делаете ничего конкретного для всех этих исключений. Если вам действительно нужно сделать что-то другое для каждого, вы в конечном итоге будете тестировать все одинаково. Поймайте только общее исключение и распечатайте его сообщение – Steve

+0

Цель не в том, чтобы проглатывать исключения Я ничего не могу поделать.Я могу сделать что-то конкретное - показать пользователю, что произошла ошибка. – Marko

+0

@Steve, то вы будете пропускать исключения StackOverflow или OutOfMemory. Текущий код фокусируется только на исключениях файлов. – Artemix

ответ

4

Исключения, которые вы указали, относятся к двум различным категориям - это указывает на ошибку кодирования, и это указывает на проблему во время выполнения. Вы абсолютно правы, что исключения в первой категории можно предотвратить: вы можете писать код таким образом, чтобы они никогда не случались. Например, если ваш код null - отслеживает путь, вы не рискуете получить ArgumentNullException по вызову ReadAllText. Давайте проанализируем оставшиеся исключения по одному:

  • IOException, DirectoryNotFoundException, FileNotFoundException - все три будут пойманы, если вы ловите IOException
  • UnauthorizedAccessException - должны быть пойманы отдельно
  • NotSupportedException - может быть предотвращено путем проверки пути до совершения вызова.
  • SecurityException - перед тем, как позвонить, может быть предотвращен checking permissions.

В конце концов, вы можете охватить все исключения, которые указывают на проблемы во время выполнения ловя IOException и UnauthorizedAccessException, и предотвращение остальных исключений из происходит путем предварительной проверки параметров, которые планируется передать и рассмотрение пробег - временная среда вашего кода.

+1

Моя проблема заключается в том, что это большая работа для простого открытия и чтения файлов. И дублированная работа - потому что Microsoft закодировала все это в .NET. Так зачем мне дублировать их работу? – Marko

+0

@Marko Это не дублируется - Microsoft сделала это для своего собственного кода кода, который отличается от вашего. Вы также можете использовать большую часть своей работы, создавая объект 'FileInfo' и видя, есть ли у вас исключения из конструктора. Если вы ничего не получите, то «ReadAllText» будет бросать одно из «IOException» или «UnauthorizedAccessException» для одного и того же пути; другие исключения не будут выбрасываться. Поместите создание 'FileInfo' в вашу проверку пути для более короткого кода. – dasblinkenlight

+0

Спасибо, я не знал об этом. Я по-прежнему думаю о своих конкретных целях (просто сообщая об ошибке пользователю), проще создать FileException и поймать только одно исключение. Поймать IOException и UnauthorizedAccessException, похоже, удваивает работу каждый раз, когда я использую ReadAllText. – Marko

3

Что вы ищете, это System.IO.IOException.

Наследование иерархии System.IO.IOException-х:

System.Object 
    System.Exception 
    System.SystemException 
     System.IO.IOException 
     System.IO.DirectoryNotFoundException 
     System.IO.DriveNotFoundException 
     System.IO.EndOfStreamException 
     System.IO.FileLoadException 
     System.IO.FileNotFoundException 
     System.IO.PathTooLongException 
     System.IO.PipeException 

ArgumentException заметно наследуется двумя известными исключениями:

System.Object 
    System.Exception 
    System.SystemException 
     System.ArgumentException 
     System.ArgumentNullException 
     System.ArgumentOutOfRangeException 
     //... 

Некоторые типичные ArithmeticException-х:

System.Object 
    System.Exception 
    System.SystemException 
     System.ArithmeticException 
     System.DivideByZeroException 
     System.NotFiniteNumberException 
     System.OverflowException 

Также следует отметить, это ThreadAbortException, который должен быть уловлен в asyn хронологические делегаты событий, используемые в настольных приложениях, или также в ASP.NET при перенаправлении/завершении HttpResponse.

Другие исключения являются слишком простыми, чтобы иметь более «специализированные исключения базы». Ищите их в ссылке System.Exception's inheritance hierarchy и в System.SystemException's inheritance hierarchy или отражением.

Смежные вопросы