7

明らかに、多くのアプリケーションがファイルを操作し、ユーザーにエラーを表示する必要があります。ただし、System.IO.File クラスのメンバーは多くの例外をスローします。これらは ReadAllText 専用です:

  • ArgumentException
  • ArgumentNullException
  • PathTooLongException
  • DirectoryNotFoundException
  • IO例外
  • UnauthorizedAccessException
  • FileNotFoundException
  • サポートされていない例外
  • セキュリティ例外

では、他の例外を飲み込まずに、それらをすべてキャッチしてユーザーに表示するにはどうすればよいでしょうか?

明らかに、完璧なコーディングを使用すると、次の 2 つを排除できます。

  • ArgumentException
  • ArgumentNullException

(おそらく面倒な) チェックを記述すれば、PathTooLongException を排除できます。しかし、なぜ Microsoft が作成したチェック用のコードを複製するのでしょうか?

ただし、すべてのチェックを行った場合でも、他の例外が発生する可能性があります。

  • DirectoryNotFoundException
  • IO例外
  • UnauthorizedAccessException
  • FileNotFoundException
  • サポートされていない例外
  • セキュリティ例外

ファイルやフォルダーは、ファイルを開くまでに削除されたり、セキュリティ権限が変更されたりする可能性があります。

ユーザーにメッセージを表示する以外に、これらのシナリオで何ができるかわかりません。OSが見つけられないディレクトリを見つけるつもりですか?権限を修正しますか? サポートされていない操作をサポートするために OS にコードを挿入しますか? LOL 可能なのは、エラーメッセージを表示することだけです。

したがって、テキストを読み取るためにファイルを開くたびにこれらすべての例外をキャッチする必要がある場合、Exception をキャッチして例外を飲み込まない限り、コードは長くて反復的でなければなりません。

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
        }

マイクロソフトがこれらすべての例外を何らかの方法でグループ化していない理由がよくわかりません。何か不足していますか、それともこれは良い習慣ですか?

4

2 に答える 2

4

リストした例外は、2 つの異なるカテゴリに分類されます。これらはコーディング エラーを示し、これらは実行時の問題を示します。最初のカテゴリの例外が回避可能であるというあなたの意見は完全に正しいです: それらが決して起こらないような方法でコードを書くことができます. たとえば、コードがパスをチェックする場合、の呼び出しにnull巻き込まれる危険はありません。残りの例外を 1 つずつ分析してみましょう。ArgumentNullExceptionReadAllText

  • IOExceptionDirectoryNotFoundExceptionFileNotFoundException - キャッチすると 3 つすべてがキャッチされますIOException
  • UnauthorizedAccessException- 別々にキャッチする必要があります
  • NotSupportedException- 呼び出しを行う前にパスを検証することで防止できます。
  • SecurityException- 呼び出しを行う前に権限を確認することで防止できます。

IOException最後に、とをキャッチすることで実行時の問題を示すすべての例外をカバーしUnauthorizedAccessException、渡す予定のパラメーターを事前に検証してコードの実行時環境を調べることで、残りの例外の発生を防ぐことができます。

于 2013-05-27T10:52:09.973 に答える
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 は、2 つのよく知られた例外によって特に継承されます。

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 の継承階層の参照およびSystem.SystemException の継承階層で、またはリフレクションによってそれらを探してください。

于 2013-05-27T11:00:24.517 に答える