C# - 这是一种简化System.IO.File.ReadAllText生成的异常的好方法

时间:2013-05-27 10:25:23

标签: c# exception-handling

显然,许多应用程序需要处理文件并向用户显示错误。然而,System.IO.File类的成员抛出了很多例外。这些仅适用于ReadAllText:

  • ArgumentException
  • ArgumentNullException
  • PathTooLongException
  • DirectoryNotFoundException
  • IOException的
  • UnauthorizedAccessException
  • FileNotFoundException异常
  • NotSupportedException异常
  • 抛出:SecurityException

那么如何抓住所有这些并将其显示给用户而不会吞下其他异常?

显然,使用完美编码,您可以消除这些2:

  • ArgumentException
  • ArgumentNullException

如果你写了一个(可能是痛苦的)检查,你可以消除PathTooLongException。但是为什么要复制代码以便微软编写检查?

但即使你做了所有检查,其他例外仍然可能发生:

  • DirectoryNotFoundException
  • IOException
  • UnauthorizedAccessException
  • FileNotFoundException
  • NotSupportedException
  • 抛出:SecurityException

文件和文件夹可能会在您打开文件时被删除,安全权限可能会发生变化等。

除了向用户显示消息外,我没有看到您在这些场景中可以做什么。你要找到操作系统找不到的目录吗?修复权限?将代码注入操作系统以支持不支持的操作?大声笑 我认为可能只显示错误信息。

因此,如果每次打开文件读取文本时都必须捕获所有这些异常,我的代码必须冗长且重复,除非我通过捕获异常来吞下异常。

创建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
        }

我真的不明白为什么微软没有以某种方式将所有这些例外分组。我错过了什么或者这是一个好习惯吗?

2 个答案:

答案 0 :(得分:4)

您列出的例外有两个不同的类别 - 这些类别表示编码错误,这些表示运行时问题。你绝对正确的是第一类中的异常是可以预防的:你可以用它们永远不会发生的方式编写代码。例如,如果您的代码null - 检查路径,那么ArgumentNullException的调用就不会有ReadAllText。让我们一个一个地分析剩下的例外:

  • IOExceptionDirectoryNotFoundExceptionFileNotFoundException - 如果您抓住IOException
  • ,这三个都会被抓住
  • UnauthorizedAccessException - 应单独抓取
  • NotSupportedException - 可以通过在拨打电话前验证路径来阻止。
  • SecurityException - 可以在拨打电话前checking permissions阻止。

最后,您可以通过捕获IOExceptionUnauthorizedAccessException来涵盖指示运行时问题的所有异常,并通过预先验证您计划的参数来防止其他异常发生传递并检查代码的运行时环境。

答案 1 :(得分: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,应该在桌面应用程序中使用的异步事件委托中捕获,或者在重定向/终止HttpResponse时在ASP.NET中捕获。

其他例外情况太基础,无法获得更多“专门的基本例外”。请参考System.Exception's inheritance hierarchySystem.SystemException's inheritance hierarchy或通过反思来查看它们。