sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  1796 随笔 :: 22 文章 :: 24 评论 :: 226万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

https://www.cnblogs.com/huhangfei/p/5012978.html

诚然可以使用现成的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>();
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
    </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">string</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> Directory.GetFileSystemEntries(dir))
    {
        </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (regexPattern == <span style="color: rgba(0, 0, 255, 1)">null</span> || Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase |<span style="color: rgba(0, 0, 0, 1)"> RegexOptions.Multiline))
            { lst.Add(item); }

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">递归</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> (recurse &amp;&amp; (File.GetAttributes(item) &amp; FileAttributes.Directory) ==<span style="color: rgba(0, 0, 0, 1)"> FileAttributes.Directory)
            { lst.AddRange(GetFileSystemEntries(item, regexPattern, </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)); }
        }
        </span><span style="color: rgba(0, 0, 255, 1)">catch</span> { <span style="color: rgba(0, 0, 255, 1)">if</span> (throwEx) { <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)">; } }
    }
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span> { <span style="color: rgba(0, 0, 255, 1)">if</span> (throwEx) { <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)">; } }

</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> 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>();

</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
    </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">string</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> Directory.GetFileSystemEntries(dir))
    {
        </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">bool</span> isFile = (File.GetAttributes(item) &amp; FileAttributes.Directory) !=<span style="color: rgba(0, 0, 0, 1)"> FileAttributes.Directory;

            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (isFile &amp;&amp; (regexPattern == <span style="color: rgba(0, 0, 255, 1)">null</span> || Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase |<span style="color: rgba(0, 0, 0, 1)"> RegexOptions.Multiline)))
            { lst.Add(item); }

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">递归</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> (recurse &amp;&amp; !isFile) { lst.AddRange(GetFiles(item, regexPattern, <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)); }
        }
        </span><span style="color: rgba(0, 0, 255, 1)">catch</span> { <span style="color: rgba(0, 0, 255, 1)">if</span> (throwEx) { <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)">; } }
    }
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span> { <span style="color: rgba(0, 0, 255, 1)">if</span> (throwEx) { <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)">; } }

</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> 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>();

</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
    </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">string</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> Directory.GetDirectories(dir))
    {
        </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (regexPattern == <span style="color: rgba(0, 0, 255, 1)">null</span> || Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase |<span style="color: rgba(0, 0, 0, 1)"> RegexOptions.Multiline))
            { lst.Add(item); }

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">递归</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> (recurse) { lst.AddRange(GetDirectories(item, regexPattern, <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)); }
        }
        </span><span style="color: rgba(0, 0, 255, 1)">catch</span> { <span style="color: rgba(0, 0, 255, 1)">if</span> (throwEx) { <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)">; } }
    }
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span> { <span style="color: rgba(0, 0, 255, 1)">if</span> (throwEx) { <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)">; } }

</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> lst.ToArray();

}

复制代码
复制代码

 

posted on   sunny123456  阅读(559)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示