2013-05-27 10 views
6

明らかに、多くのアプリケーションでファイルを操作し、エラーをユーザーに表示する必要があります。しかし、System.IO.Fileクラスのメンバーは多くの例外をスローします。これらは、ちょうどReadAllTextためのものです:C# - System.IO.File.ReadAllTextによって生成された例外を単純化するための良い習慣です

  • ArgumentExceptionが
  • 例外ArgumentNullException
  • PathTooLongException
  • DirectoryNotFoundException
  • にIOException
  • UnauthorizedAccessException
  • にFileNotFoundException
  • 非サポート例外
  • SecurityExceptionが

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

明らかにあなたは排除することができますコーディング完璧これら2:

  • ArgumentExceptionが
  • 例外ArgumentNullException

あなたは(おそらく痛みを伴う)を記述する場合は、あなたがPathTooLongExceptionを排除することができます確認してください。しかし、なぜマイクロソフトが書いたチェック用のコードを複製するのですか?

しかし、あなたはすべてのチェックをした場合でも、他の例外がまだ発生します

  • DirectoryNotFoundException
  • にIOException
  • UnauthorizedAccessException
  • にFileNotFoundException
  • 非サポート例外
  • SecurityExceptionが

ファイルとフォルダがファイルを開く時間によって削除得ることができ、セキュリティ権限は、私はあなたがユーザーに表示メッセージを除き、これらのシナリオで何ができるかが表示されない

など変更することができます。 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 
     } 

Microsoftがテーマと連動すべてのそれらの例外をグループ化していない理由を私は本当に理解していません何らかの方法で。私は何かを逃しているのですか、この良い練習ですか?

+1

しかし、実際の結果はどうですか?あなたはこれらの例外すべてに特化した何もしません。あなたが本当にそれぞれ違うことをしなければならない場合は、同じ方法ですべてをテストすることになります。ジェネリック例外をキャッチしてそのメッセージを表示 – Steve

+0

目的は例外を飲み込むことではありません私は何もできません。私は何か特定のことをすることができます - エラーが発生したことをユーザーに示します。 – Marko

+0

@ SteveあなたはStackOverflow例外またはOutOfMemory例外を見逃します。現在のコードはFile例外のみに焦点を当てています。 – Artemix

答えて

4

表示されている例外は、2つの異なるカテゴリにあります。これらは、コーディングエラーを示すもので、実行時の問題を示しています。第1カテゴリの例外は予防可能であることは間違いありません。発生しないような方法でコードを書くことができます。たとえば、コードnullがパスをチェックすると、ReadAllTextのコールでArgumentNullExceptionを取得する危険性はありません。一つで、残りの例外を1つずつ分析してみましょう:

  • IOExceptionDirectoryNotFoundExceptionFileNotFoundException - あなたはIOException
  • UnauthorizedAccessExceptionをキャッチした場合、3つすべてが捕捉されます - 個別
  • NotSupportedExceptionをキャッチする必要があります - 通話を行う前にパスを確認することで防止できます。
  • SecurityException - は電話をかける前にchecking permissionsによって防ぐことができます。最後に

、あなたはIOExceptionUnauthorizedAccessExceptionをキャッチし、あなたが合格する予定のパラメータを事前に検証し、実行を調べることによって起こってから例外の残りを防止することにより、実行時の問題を示しているすべての例外をカバーすることができますあなたのコードの時間環境。

+1

私の問題は、これは単純なファイルのオープンと読み取りのための多くの作業であるということです。そして、重複した作業 - マイクロソフトではこれらのすべてを.NETでコーディングしているためです。だから私はなぜ彼らの作品を複製するだろうか? – Marko

+0

@Markoそれは重複していません - マイクロソフトはあなたのものとは異なる独自のコードパスのためにそれを行いました。 'FileInfo'オブジェクトを作成し、コンストラクタから例外を受け取ったかどうかを確認することで、ほとんどの作業を再利用することができます。何も取得しなければ、 'ReadAllText'は同じパスに対して' IOException'または 'UnauthorizedAccessException'のいずれかを投げます。他の例外は投げられません。はるかに短いコードのパスの検証に 'FileInfo'の作成を入れてください。 – dasblinkenlight

+0

ありがとう、私はこれを知らなかった。私はまだ私の具体的な目的(ちょうどユーザーにエラーを報告する)と思うFileExceptionを作成し、その1つの例外をキャッチ簡単です。 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が、特に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です。これはasynでキャッチする必要がありますデスクトップアプリケーションやHttpResponseのリダイレクト/終了時にASP.NETで使用されるイベントイベントの代理人です。

その他の例外は、「特殊なベース例外」を持つにはあまりにも基本的です。 System.Exception's inheritance hierarchyの参照とSystem.SystemException's inheritance hierarchyの参照または反射によってそれらを見てください。

関連する問題