C#中DirectoryInfo.GetFiles使用注意事项

在一个文件夹内搜索指定格式的所有文件是一个十分常用的操作,通常使用DirectoryInfo.GetFiles 的方法。

在.NET Framework中,它有三个重载:

(1)GetFiles():返回当前目录下所有文件,不包括文件夹;

(2)GetFiles (string searchPattern):返回当前目录下与搜索字符串匹配的所有文件,不包括文件夹;

(3)GetFiles (string searchPattern, SearchOption searchOption):返回当前目录(或包括子目录)下与搜索字符串匹配的所有文件;

在.NET中,它有四个重载,多了一个:

(4)GetFiles(String, EnumerationOptions):返回当前目录下与搜索字符串、枚举类型(文件大小 、是否包括子目录等)匹配的所有文件,不包括文件夹。

但在应用过程中需要注意以下问题:

一、模糊搜索

搜索字符串searchPattern支持*(零个或多个字符)和?(零个或一个字符)两种通配符,但不支持正则表达式,也不支持类似"*.txt|*.xls"这样的过滤器,多个格式过滤使用以下方式实现:

static void Test1()
{
    Console.WriteLine("多格式搜索1:");
    var files1 =new DirectoryInfo(@"D:\搜索测试\Data").GetFiles("*.xls");
    var files2 = new DirectoryInfo(@"D:\搜索测试\Data").GetFiles( "*.txt");
    var files = files1.Union(files2);
    foreach (var file in files)
    {
        Console.WriteLine(file);
    }
    Console.WriteLine();
}
static void Test2()
{
    Console.WriteLine("多格式搜索2:");
    var allFiles = new DirectoryInfo(@"D:\搜索测试\Data").GetFiles("*.*");
    var files = allFiles.Where(s => s.FullName.EndsWith(".xls") || s.FullName.EndsWith(".txt")).ToList();
    foreach (var file in files)
    {
        Console.WriteLine(file);
    }
    Console.WriteLine();
}

二、格式过滤

使用通配符过滤的,要注意官网做了如下解释:

文件扩展名正好为三个字符的 将返回扩展名为三个或多个字符的文件,其中前三个字符与 中指定的文件 searchPattern 扩展名匹配 searchPattern 。 searchPattern文件扩展名为 1、2 或 3 以上字符的 仅返回扩展名与 中指定的文件扩展名完全匹配的文件 searchPattern。

以下列表显示了 参数的不同长度 searchPattern 的行为:

"*.abc"返回扩展名为.abc、.abcd、.abcde、.abcdef 等的文件。

"*.abcd"仅返回扩展名为.abcd 的文件。

"*.abcde"仅返回扩展名为.abcde 的文件。

"*.abcdef"仅返回扩展名为.abcdef 的文件。

但实际测试结果,部分电脑是这样的,但部分电脑不是这样的,暂不清楚原因。

static void Test3()
{
    Console.WriteLine("格式过滤:");
    var files = new DirectoryInfo(@"D:\搜索测试\Data").GetFiles("*.xls");
    foreach (var file in files)
    {
        Console.WriteLine(file.FullName);
    }
    Console.WriteLine();
}

三、搜索效率

GetFiles比EnumerateFiles慢得多,尤其是大数据量下很明显。这是因为GetFiles要创建大量FileInfo对象非常耗时。

static void Test4()
{
    Console.WriteLine("搜索效率:");
    var files = new DirectoryInfo(@"D:\搜索测试\Data")
        .EnumerateFiles()
        .AsParallel()
        .Where(s=> s.FullName.EndsWith(".xls"))
        .ToList();
            
    foreach (var file in files)
    {
        Console.WriteLine(file.FullName);
    }
    Console.WriteLine();
}

也可尝试使用AsParallel并行、Win32函数FindNextFile来优化和提高查询速度。

参考资料

DirectoryInfo.GetFiles 方法 (System.IO) | Microsoft Learn

c# - Improve the performance for enumerating files and folders using .NET - Stack Overflow

posted @ 2024-01-05 11:01  我也是个傻瓜  阅读(2110)  评论(0编辑  收藏  举报