C # - гэта добрая практыка, каб спрасціць выключэння, згенераваныя System.IO.File.ReadAllText

Відавочна, што шмат прыкладанняў трэба будзе працаваць з файламі і адлюстраванне памылак карыстальнікаў. Аднак члены супольнасці класа 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 не групавацца ўсе гэтыя выключэннямі Снягуркі ў некаторым родзе. Ці магу я нешта адсутнічае, ці гэта добрая практыка?

6
@Marko І як бы Microsoft ведаць, якія вашыя намеры?
дададзена аўтар Steve, крыніца
@Marko І як бы Microsoft ведаць, якія вашыя намеры?
дададзена аўтар Steve, крыніца
@Marko І як бы Microsoft ведаць, якія вашыя намеры?
дададзена аўтар Steve, крыніца
Але які практычны вынік гэтага? Вы нічога канкрэтнага для ўсіх гэтых выключэнняў не робяць. Калі вы сапраўды павінны зрабіць нешта іншае для кожнага з іх вы ў канчатковым выніку тэставання кожны такім жа чынам. Злавіць толькі агульныя выключэння і для вываду паведамлення
дададзена аўтар Steve, крыніца
@Steve тады вы прапусціце StackOverflow або OutOfMemory выключэнні. Бягучы код факусуюць толькі на выключэнні файлаў.
дададзена аўтар Artemix, крыніца
@Steve тады вы прапусціце StackOverflow або OutOfMemory выключэнні. Бягучы код факусуюць толькі на выключэнні файлаў.
дададзена аўтар Artemix, крыніца
@Steve тады вы прапусціце StackOverflow або OutOfMemory выключэнні. Бягучы код факусуюць толькі на выключэнні файлаў.
дададзена аўтар Artemix, крыніца
Мэта не глытаць выключэння, я нічога не магу зрабіць. Я магу зрабіць нешта канкрэтнае - паказаць карыстальнік, што адбылася памылка.
дададзена аўтар Marko, крыніца

8 адказы

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

  • IOException, DirectoryNotFoundException, FileNotFoundException - all three will be caught if you catch IOException
  • UnauthorizedAccessException - should be caught separately
  • NotSupportedException - can be prevented by validating the path before making the call.
  • SecurityException - can be prevented by checking permissions before making the call.

У рэшце рэшт, вы можаце ахапіць усе выключэння, якія паказваюць на праблемы падчас выканання ловячы IOException і UnauthorizedAccessException , а таксама прадухіленне астатніх выключэнняў з адбываецца шляхам папярэдняй праверкі параметраў вы плануеце прайсці і вывучэнне асяроддзя выканання вашага кода.

4
дададзена
@Marko Гэта не дублюецца - Microsoft зрабіла гэта для свайго канкрэтнага шляху кода, які адрозніваецца ад вашага. Вы можаце паўторна выкарыстоўваць большую частку сваёй працы, таксама, пабудаваўшы FileInfo аб'ект, і, бачачы, калі вы атрымліваеце якія-небудзь выключэння з канструктара. Калі вы нічога не атрымаеце, а затым ReadAllText выкіне адзін з IOException або UnauthorizedAccessException для таго ж шляху; іншыя выключэння не будуць выкінутыя. Змешчаны стварэнне FileInfo ў вашай праверкі шляху значна больш кароткі код.
дададзена аўтар dasblinkenlight, крыніца
Дзякуй, я не ведаў пра гэта. Я да гэтага часу думаю, што для маіх канкрэтных мэтаў (толькі паведамленні пра памылку для карыстальніка), што лягчэй стварыць FileException і злавіць толькі што адно выключэнне. Лоўля IOException і UnauthorizedAccessException здаецца, падвойваючы праца кожны раз, калі я выкарыстоўваю ReadAllText.
дададзена аўтар Marko, крыніца
Мая праблема заключаецца ў тым, што гэта шмат працы для простага адкрыцця файла і чытання. І дублюецца праца - таму што Microsoft закадзіраваў усё гэта ў .NET. Дык чаму б мне дубляваць іх працу?
дададзена аўтар Marko, крыніца

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

  • IOException, DirectoryNotFoundException, FileNotFoundException - all three will be caught if you catch IOException
  • UnauthorizedAccessException - should be caught separately
  • NotSupportedException - can be prevented by validating the path before making the call.
  • SecurityException - can be prevented by checking permissions before making the call.

У рэшце рэшт, вы можаце ахапіць усе выключэння, якія паказваюць на праблемы падчас выканання ловячы IOException і UnauthorizedAccessException , а таксама прадухіленне астатніх выключэнняў з адбываецца шляхам папярэдняй праверкі параметраў вы плануеце прайсці і вывучэнне асяроддзя выканання вашага кода.

4
дададзена
@Marko Гэта не дублюецца - Microsoft зрабіла гэта для свайго канкрэтнага шляху кода, які адрозніваецца ад вашага. Вы можаце паўторна выкарыстоўваць большую частку сваёй працы, таксама, пабудаваўшы FileInfo аб'ект, і, бачачы, калі вы атрымліваеце якія-небудзь выключэння з канструктара. Калі вы нічога не атрымаеце, а затым ReadAllText выкіне адзін з IOException або UnauthorizedAccessException для таго ж шляху; іншыя выключэння не будуць выкінутыя. Змешчаны стварэнне FileInfo ў вашай праверкі шляху значна больш кароткі код.
дададзена аўтар dasblinkenlight, крыніца
Дзякуй, я не ведаў пра гэта. Я да гэтага часу думаю, што для маіх канкрэтных мэтаў (толькі паведамленні пра памылку для карыстальніка), што лягчэй стварыць FileException і злавіць толькі што адно выключэнне. Лоўля IOException і UnauthorizedAccessException здаецца, падвойваючы праца кожны раз, калі я выкарыстоўваю ReadAllText.
дададзена аўтар Marko, крыніца
Мая праблема заключаецца ў тым, што гэта шмат працы для простага адкрыцця файла і чытання. І дублюецца праца - таму што Microsoft закадзіраваў усё гэта ў .NET. Дык чаму б мне дубляваць іх працу?
дададзена аўтар Marko, крыніца

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

  • IOException, DirectoryNotFoundException, FileNotFoundException - all three will be caught if you catch IOException
  • UnauthorizedAccessException - should be caught separately
  • NotSupportedException - can be prevented by validating the path before making the call.
  • SecurityException - can be prevented by checking permissions before making the call.

У рэшце рэшт, вы можаце ахапіць усе выключэння, якія паказваюць на праблемы падчас выканання ловячы IOException і UnauthorizedAccessException , а таксама прадухіленне астатніх выключэнняў з адбываецца шляхам папярэдняй праверкі параметраў вы плануеце прайсці і вывучэнне асяроддзя выканання вашага кода.

4
дададзена
@Marko Гэта не дублюецца - Microsoft зрабіла гэта для свайго канкрэтнага шляху кода, які адрозніваецца ад вашага. Вы можаце паўторна выкарыстоўваць большую частку сваёй працы, таксама, пабудаваўшы FileInfo аб'ект, і, бачачы, калі вы атрымліваеце якія-небудзь выключэння з канструктара. Калі вы нічога не атрымаеце, а затым ReadAllText выкіне адзін з IOException або UnauthorizedAccessException для таго ж шляху; іншыя выключэння не будуць выкінутыя. Змешчаны стварэнне FileInfo ў вашай праверкі шляху значна больш кароткі код.
дададзена аўтар dasblinkenlight, крыніца
Мая праблема заключаецца ў тым, што гэта шмат працы для простага адкрыцця файла і чытання. І дублюецца праца - таму што Microsoft закадзіраваў усё гэта ў .NET. Дык чаму б мне дубляваць іх працу?
дададзена аўтар Marko, крыніца
Дзякуй, я не ведаў пра гэта. Я да гэтага часу думаю, што для маіх канкрэтных мэтаў (толькі паведамленні пра памылку для карыстальніка), што лягчэй стварыць FileException і злавіць толькі што адно выключэнне. Лоўля IOException і UnauthorizedAccessException здаецца, падвойваючы праца кожны раз, калі я выкарыстоўваю ReadAllText.
дададзена аўтар Marko, крыніца

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

  • IOException, DirectoryNotFoundException, FileNotFoundException - all three will be caught if you catch IOException
  • UnauthorizedAccessException - should be caught separately
  • NotSupportedException - can be prevented by validating the path before making the call.
  • SecurityException - can be prevented by checking permissions before making the call.

У рэшце рэшт, вы можаце ахапіць усе выключэння, якія паказваюць на праблемы падчас выканання ловячы IOException і UnauthorizedAccessException , а таксама прадухіленне астатніх выключэнняў з адбываецца шляхам папярэдняй праверкі параметраў вы плануеце прайсці і вывучэнне асяроддзя выканання вашага кода.

4
дададзена
@Marko Гэта не дублюецца - Microsoft зрабіла гэта для свайго канкрэтнага шляху кода, які адрозніваецца ад вашага. Вы можаце паўторна выкарыстоўваць большую частку сваёй працы, таксама, пабудаваўшы FileInfo аб'ект, і, бачачы, калі вы атрымліваеце якія-небудзь выключэння з канструктара. Калі вы нічога не атрымаеце, а затым ReadAllText выкіне адзін з IOException або UnauthorizedAccessException для таго ж шляху; іншыя выключэння не будуць выкінутыя. Змешчаны стварэнне FileInfo ў вашай праверкі шляху значна больш кароткі код.
дададзена аўтар dasblinkenlight, крыніца
Дзякуй, я не ведаў пра гэта. Я да гэтага часу думаю, што для маіх канкрэтных мэтаў (толькі паведамленні пра памылку для карыстальніка), што лягчэй стварыць FileException і злавіць толькі што адно выключэнне. Лоўля IOException і UnauthorizedAccessException здаецца, падвойваючы праца кожны раз, калі я выкарыстоўваю ReadAllText.
дададзена аўтар Marko, крыніца
Мая праблема заключаецца ў тым, што гэта шмат працы для простага адкрыцця файла і чытання. І дублюецца праца - таму што Microsoft закадзіраваў усё гэта ў .NET. Дык чаму б мне дубляваць іх працу?
дададзена аўтар Marko, крыніца

Што вы шукаеце з'яўляецца 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 , якія павінны быць злоўленай ў асінхроннай дэлегаты падзей, якія выкарыстоўваюцца ў настольных прыкладаннях, ці ж у ASP.NET пры перанакіраванні/спынення HttpResponse.

Іншыя выключэння занадта асноўныя, каб мець больш «спецыялізаваныя базавыя выключэння». Паглядзіце на іх у якасці спасылкі на іерархіі атрымання ў спадчыну System.Exception ў </а> і System.SystemException ў іерархіі атрымання ў спадчыну або адлюстраванне.

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 , якія павінны быць злоўленай ў асінхроннай дэлегаты падзей, якія выкарыстоўваюцца ў настольных прыкладаннях, ці ж у ASP.NET пры перанакіраванні/спынення HttpResponse.

Іншыя выключэння занадта асноўныя, каб мець больш «спецыялізаваныя базавыя выключэння». Паглядзіце на іх у якасці спасылкі на іерархіі атрымання ў спадчыну System.Exception ў </а> і System.SystemException ў іерархіі атрымання ў спадчыну або адлюстраванне.

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 , якія павінны быць злоўленай ў асінхроннай дэлегаты падзей, якія выкарыстоўваюцца ў настольных прыкладаннях, ці ж у ASP.NET пры перанакіраванні/спынення HttpResponse.

Іншыя выключэння занадта асноўныя, каб мець больш «спецыялізаваныя базавыя выключэння». Паглядзіце на іх у якасці спасылкі на іерархіі атрымання ў спадчыну System.Exception ў </а> і System.SystemException ў іерархіі атрымання ў спадчыну або адлюстраванне.

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 , якія павінны быць злоўленай ў асінхроннай дэлегаты падзей, якія выкарыстоўваюцца ў настольных прыкладаннях, ці ж у ASP.NET пры перанакіраванні/спынення HttpResponse.

Іншыя выключэння занадта асноўныя, каб мець больш «спецыялізаваныя базавыя выключэння». Паглядзіце на іх у якасці спасылкі на іерархіі атрымання ў спадчыну System.Exception ў </а> і System.SystemException ў іерархіі атрымання ў спадчыну або адлюстраванне.

3
дададзена