C#/.NET 如何確認一個路徑是否是合法的文件路徑

  • 2020 年 2 月 10 日
  • 筆記

很多方法要求傳入一個字元串作為文件名或者文件路徑,不過方法在實際執行到使用文件名的時候才會真正使用到這個文件名;於是這這種時候才會因為各種各樣的異常發現文件名或者文件路徑是不合法的。

有沒有方法能夠提前驗證文件名或者文件路徑是否是合法的路徑呢?


這是一個不幸的結論 —— 沒有!

實際上由我們自己寫程式碼判斷一個字元串是否是一個合法的文件路徑是非常困難的,因為:

  1. 不同作業系統的路徑格式是不同的;
  2. 同一個作業系統有各種各樣不同的路徑用途。

但你可能會說,就算有各種不同,也是可以窮舉出來的。那麼來看看窮舉這些不同的情況需要多少程式碼吧:

看完這些程式碼,你是不是可以考慮放棄做 100% 精確的提前驗證了?放棄是正解。

那麼接下來如何驗證呢?

使用 new FileInfo(string fileName) 類型和 Path.GetFullPath(string path) 方法來判斷,則會使用到以上的程式碼,不過副作用是在路徑不合法的時候拋出異常。

然而作為 API,驗證路徑的合法性也是需要拋出異常的,所以大可以繼續使用這樣的方法,用方法內部拋出的異常來提醒開發者傳入的路徑不合法。

但有時候是作為與用戶的交互來判斷路徑或者文件名是否合法的,那麼這個時候使用異常就不太合適了。畢竟 C#/.NET 的異常機制不應該參與正常的邏輯流程。

那麼可以使用 Path.GetInvalidFileNameChars()GetInvalidPathChars() 來判斷字元串中是否包含不合法的文件名字元或者路徑字元。

以下程式碼來自 .NET Core 的庫源碼 Path.Windows.cs

public static char[] GetInvalidFileNameChars() => new char[]  {      '"', '<', '>', '|', '',      (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,      (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,      (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,      (char)31, ':', '*', '?', '\', '/'  };    public static char[] GetInvalidPathChars() => new char[]  {      '|', '',      (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,      (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,      (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,      (char)31  };

參考資料

本文會經常更新,請閱讀原文: https://blog.walterlv.com/post/verify-a-st

本作品採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名 呂毅 (包含鏈接: https://blog.walterlv.com ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發布。如有任何疑問,請 與我聯繫 ([email protected])