標籤:style blog http io color ar 使用 sp for
先別急著噴,請聽我解釋。
誠然可以使用現成的Directory類下的GetFiles、GetDirectories、GetFileSystemEntries這幾個方法實現同樣的功能,但請相信我不是蛋疼,原因是這幾個方法在遇上【System Volume Information】這種目錄時,極有可能會給你個拒絕訪問的異常,想跳過都不行。所以沒辦法,重新實現了一下。
實現說明:
- 仍然是基於對Directory類的幾個方法的封裝進行實現,只是沒有使用它們的searchPattern和searchOption功能
- 將匹配模式由windows的萬用字元?、*改為正則匹配。一是讓匹配更強大,二是要實現?*匹配還得做額外工作,沒必要
匹配模式並沒有預設添加首尾限定^$,即“abc"將會匹配所有包含該字串的項目,所以如果你要匹配首尾,請自行添加^$
忽略大小寫匹配
如果不想搜尋指定項目而是全部,請將regexPattern參數設為null,而不是.*,前者效能更好
- 可通過設定recurse和throwEx參數決定是否遞迴搜尋,和是否拋異常。預設是不遞迴,不拋異常
- 遇到不可訪問的目錄會跳過。當然前提是throwEx=false
- 之所以在foreach外層再套一層try-catch,是因為如果指定的dir就是不可訪問的目錄,那也可以避免異常
- 之所以為擷取項、擷取檔案、擷取目錄分別實現3個方法,而不是只實現一個擷取項,另外兩個重載,是因為只實現一個的話,foreach中要做的邏輯判斷不少,考慮到方法是要遞迴的,所以迴圈中邏輯越少越好
- 之所以不做dir參數合法性檢查,原因同上,判斷越少越好。所以請使用者調用前自行確保dir合法
不廢話,上代碼:
/// <summary>/// 擷取指定目錄中的匹配項(檔案或目錄)/// </summary>/// <param name="dir">要搜尋的目錄</param>/// <param name="regexPattern">項名模式(正則)。null表示忽略模式比對,返回所有項</param>/// <param name="recurse">是否搜尋子目錄</param>/// <param name="throwEx">是否拋異常</param>/// <returns></returns>private static string[] GetFileSystemEntries(string dir, string regexPattern = null, bool recurse = false, bool throwEx = false){ List<string> lst = new List<string>(); try { foreach (string item in Directory.GetFileSystemEntries(dir)) { try { if (regexPattern == null || Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline)) { lst.Add(item); } //遞迴 if (recurse && (File.GetAttributes(item) & FileAttributes.Directory) == FileAttributes.Directory) { lst.AddRange(GetFileSystemEntries(item, regexPattern, true)); } } catch { if (throwEx) { throw; } } } } catch { if (throwEx) { throw; } } return lst.ToArray();}/// <summary>/// 擷取指定目錄中的匹配檔案/// </summary>/// <param name="dir">要搜尋的目錄</param>/// <param name="regexPattern">檔案名稱模式(正則)。null表示忽略模式比對,返回所有檔案</param>/// <param name="recurse">是否搜尋子目錄</param>/// <param name="throwEx">是否拋異常</param>/// <returns></returns>private static string[] GetFiles(string dir, string regexPattern = null, bool recurse = false, bool throwEx = false){ List<string> lst = new List<string>(); try { foreach (string item in Directory.GetFileSystemEntries(dir)) { try { bool isFile = (File.GetAttributes(item) & FileAttributes.Directory) != FileAttributes.Directory; if (isFile && (regexPattern == null || Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline))) { lst.Add(item); } //遞迴 if (recurse && !isFile) { lst.AddRange(GetFiles(item, regexPattern, true)); } } catch { if (throwEx) { throw; } } } } catch { if (throwEx) { throw; } } return lst.ToArray();}/// <summary>/// 擷取指定目錄中的匹配目錄/// </summary>/// <param name="dir">要搜尋的目錄</param>/// <param name="regexPattern">目錄名模式(正則)。null表示忽略模式比對,返回所有目錄</param>/// <param name="recurse">是否搜尋子目錄</param>/// <param name="throwEx">是否拋異常</param>/// <returns></returns>private static string[] GetDirectories(string dir, string regexPattern = null, bool recurse = false, bool throwEx = false){ List<string> lst = new List<string>(); try { foreach (string item in Directory.GetDirectories(dir)) { try { if (regexPattern == null || Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline)) { lst.Add(item); } //遞迴 if (recurse) { lst.AddRange(GetDirectories(item, regexPattern, true)); } } catch { if (throwEx) { throw; } } } } catch { if (throwEx) { throw; } } return lst.ToArray();}
- 文畢 -
【C#】遞迴搜尋指定目錄下的指定項目(檔案或目錄)