在一个文件夹内搜索指定格式的所有文件是一个十分常用的操作,通常使用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