【C#】递归搜索指定目录下的指定项目(文件或目录)

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

---------------更新:201411201121---------------

主要更新说明:将原boolrecurse参数改为intdepth,这样可以指定递归深度,而不是笼统的是否递归

先别急着喷,请听我解释。

诚然可以使用现成的Directory类下的GetFiles、GetDirectories、GetFileSystemEntries这几个方法实现同样的功能,但请相信我不是蛋疼,原因是这几个方法在遇上【System Volume Information】这种目录时,极有可能会给你个拒绝访问的异常,想跳过都不行。关于这个问题,在MSDN也有说明:

http://msdn.microsoft.com/zh-cn/library/bb513869(v=vs.90).aspx

所以没办法,重新实现了一下。

实现说明:

- 仍然是基于对Directory类的几个方法的封装进行实现,只是没有使用它们的searchPattern和searchOption功能

- 将匹配模式由windows的通配符?、*改为正则匹配。一是让匹配更强大,二是要实现?*匹配还得做额外工作,没必要

匹配模式并没有默认添加首尾限定^$,即“abc"将会匹配所有包含该字串的项目,所以如果你要匹配首尾,请自行添加^$

忽略大小写匹配

如果不想搜索指定项目而是全部,请将regexPattern参数设为null,而不是.*,前者性能更好

- 可设置depth参数指定递归搜索的深度,默认为0,表示仅搜索顶级项目,正数表示往下钻几层,负数表示不限

- 可设置throwEx参数指示是否抛异常。默认是不抛,此时遇到不可访问的目录会跳过,继续遍历

- 之所以在foreach外层再套一层try-catch,是因为如果指定的dir就是不可访问的目录,那也可以避免异常。此时返回string[0]

- 之所以为获取项、获取文件、获取目录分别实现3个方法,而不是只实现一个获取项,另外两个重载,是因为只实现一个的话,foreach中要做的逻辑判断不少,考虑到方法是要递归的,所以循环中逻辑越少越好

- 之所以不做dir参数合法性检查,原因同上,判断越少越好。所以请用户调用前自行确保dir合法

废话完,上代码:

///<summary>///获取指定目录中的匹配项(文件或目录)///</summary>///<param name="dir">要搜索的目录</param>///<param name="regexPattern">项名模式(正则)。null表示忽略模式匹配,返回所有项</param>///<param name="depth">递归深度。负数表示不限,0表示仅顶级</param>///<param name="throwEx">是否抛异常</param>///<returns></returns>publicstaticstring[] GetFileSystemEntries(stringdir,stringregexPattern =null,intdepth =0,boolthrowEx =false)

{

List<string> lst =newList<string>();try{foreach(stringiteminDirectory.GetFileSystemEntries(dir))

{try{if(regexPattern ==null|| Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase |RegexOptions.Multiline))

{ lst.Add(item); }//递归if(depth !=0&& (File.GetAttributes(item) & FileAttributes.Directory) ==FileAttributes.Directory)

{ lst.AddRange(GetFileSystemEntries(item, regexPattern, depth-1, throwEx)); }

}catch{if(throwEx) {throw; } }

}

}catch{if(throwEx) {throw; } }returnlst.ToArray();

}///<summary>///获取指定目录中的匹配文件///</summary>///<param name="dir">要搜索的目录</param>///<param name="regexPattern">文件名模式(正则)。null表示忽略模式匹配,返回所有文件</param>///<param name="depth">递归深度。负数表示不限,0表示仅顶级</param>///<param name="throwEx">是否抛异常</param>///<returns></returns>publicstaticstring[] GetFiles(stringdir,stringregexPattern =null,intdepth =0,boolthrowEx =false)

{

List<string> lst =newList<string>();try{foreach(stringiteminDirectory.GetFileSystemEntries(dir))

{try{boolisFile = (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(depth !=0&& !isFile) { lst.AddRange(GetFiles(item, regexPattern, depth -1, throwEx)); }

}catch{if(throwEx) {throw; } }

}

}catch{if(throwEx) {throw; } }returnlst.ToArray();

}///<summary>///获取指定目录中的匹配目录///</summary>///<param name="dir">要搜索的目录</param>///<param name="regexPattern">目fu录名模式(正则)。null表示忽略模式匹配,返回所有目录</param>///<param name="depth">递归深度。负数表示不限,0表示仅顶级</param>///<param name="throwEx">是否抛异常</param>///<returns></returns>publicstaticstring[] GetDirectories(stringdir,stringregexPattern =null,intdepth =0,boolthrowEx =false)

{

List<string> lst =newList<string>();try{foreach(stringiteminDirectory.GetDirectories(dir))

{try{if(regexPattern ==null|| Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase |RegexOptions.Multiline))

{ lst.Add(item); }//递归if(depth !=0) { lst.AddRange(GetDirectories(item, regexPattern, depth -1, throwEx)); }

}catch{if(throwEx) {throw; } }

}

}catch{if(throwEx) {throw; } }returnlst.ToArray();

}

- 文毕 -

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航