2013-05-27 43 views
6

顯然,很多應用程序需要處理文件並向用戶顯示錯誤。然而System.IO.File類的成員會拋出很多異常。這些只是爲ReadAllText:C# - 這是一個很好的實踐來簡化由System.IO.File.ReadAllText產生的異常

  • 的ArgumentException
  • ArgumentNullException
  • PathTooLongException
  • DirectoryNotFoundException
  • IOException異常
  • UnauthorizedAccessException
  • FileNotFoundException異常
  • NotSupportedException異常
  • 拋出:SecurityException

因此,如何趕上他們並將其展示給用戶,而不是吞嚥其他異常?

顯然與完美編碼可以消除這些2:

  • 的ArgumentException
  • ArgumentNullException

如果你寫一個(可能是痛苦的)檢查您可以消除PathTooLongException。但是,爲什麼要複製微軟編寫的檢查代碼?

但其他例外仍然可以,即使你做了所有的檢查發生:

  • DirectoryNotFoundException
  • IOException異常
  • UnauthorizedAccessException
  • FileNotFoundException異常
  • NotSupportedException異常
  • 拋出:SecurityException

文件和文件夾可以用您打開該文件時被刪除,安全權限可以改變等

我不明白,你可以在這些情況下做什麼,除了顯示消息的用戶。你會找到操作系統無法找到的目錄嗎?修復權限?將代碼注入OS以支持不受支持的操作? 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 
     } 

我真的不明白,爲什麼微軟沒有分組的所有這些異常togather某種程度上來說。我錯過了什麼,或者這是一個好習慣嗎?

+1

但是這樣的實際結果是什麼?對於所有這些例外情況,您都不做任何具體的事情如果你真的必須爲每一個做不同的事情,你最終會以同樣的方式測試每一個。只抓住通用異常並打印其消息 – Steve

+0

目的不是吞下異常,我什麼也做不了。我可以做一些特定的事情 - 向用戶顯示發生錯誤。 – Marko

+0

@Steve然後你會錯過StackOverflow或OutOfMemory異常。目前的代碼只關注文件例外。 – Artemix

回答

4

您列出的例外有兩個不同的類別 - 這些表示編碼錯誤,這些表示運行時問題。您絕對正確的是,第一類中的異常是可以預防的:您可以以永不會發生的方式編寫代碼。例如,如果您的代碼爲null - 檢查路徑,那麼在ReadAllText的調用中您不會遇到ArgumentNullException的危險。讓我們來分析一個剩餘的例外之一:

  • IOExceptionDirectoryNotFoundExceptionFileNotFoundException - 所有這三個會被抓住,如果你趕上IOException
  • UnauthorizedAccessException - 應分別抓住
  • NotSupportedException - 可以通過在撥打電話之前驗證路徑來阻止。
  • SecurityException - 在撥打電話前可以通過checking permissions阻止。

最後,你可以通過捕捉IOExceptionUnauthorizedAccessException,並防止異常的其餘部分由發生預驗證的參數,您計劃傳遞並檢查運行覆蓋指示運行時問題的所有異常代碼的時間環境。

+1

我的問題是,這是很多簡單的文件打開和閱讀的工作。重複的工作 - 因爲微軟在.NET中編寫了所有這些代碼。那麼,爲什麼我會重複他們的工作? – Marko

+0

@Marko它沒有被複制 - 微軟爲自己的特定代碼路徑做了它,這與你的不同。你也可以通過構建一個'FileInfo'對象來重用他們的大部分工作,並且看看你是否從構造函數中得到任何異常。如果你沒有得到任何東西,那麼'ReadAllText'將爲同一條路徑拋出'IOException'或'UnauthorizedAccessException'之一;其他異常不會被拋出。將FileInfo創建爲驗證路徑的更短代碼。 – dasblinkenlight

+0

謝謝,我不知道這一點。我仍然認爲我的具體目的(只是向用戶報告錯誤),創建FileException並捕獲這一個異常更容易。每次使用ReadAllText時,捕獲IOException和UnauthorizedAccessException似乎都使工作翻倍。 – 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尤其是由兩位著名的例外繼承:

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的參考文獻中或通過反思查看它們。

相關問題