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

Mar*_*rko 6 c# exception-handling

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

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

那么如何抓住它们并将其显示给用户而不会吞下其他异常?

显然,通过完美的编码,您可以消除这些2:

  • ArgumentException的
  • ArgumentNullException

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

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

  • 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 );
        }
    }    
}
Run Code Online (Sandbox Code Playgroud)

然后在捕获异常时我只需要写这个:

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

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

das*_*ght 4

您列出的异常分为两个不同的类别 - 这些异常指示编码错误,这些异常指示运行时问题。您完全正确,第一类异常是可以预防的:您可以以永远不会发生的方式编写代码。例如,如果您的代码null检查路径,那么您就不会遇到ArgumentNullException调用ReadAllText. 我们来一一分析剩下的异常:

  • IOException, DirectoryNotFoundException,FileNotFoundException - 如果你抓住的话,三个人都会被抓住IOException
  • UnauthorizedAccessException- 应单独捕获
  • NotSupportedException- 可以通过在调用之前验证路径来防止。
  • SecurityException- 可以通过在拨打电话之前检查权限来阻止。

最后,您可以通过捕获IOException和来覆盖所有表明运行时问题UnauthorizedAccessException的异常,并通过预先验证您计划传递的参数并检查代码的运行时环境来防止其余异常的发生。