您无法使用简单的 LINQ 方法完全满足您的需求。您将需要编写一个递归例程而不是使用SearchOption.AllDirectories。原因是您要过滤 directories 而不是 files。
您可以使用以下静态方法来实现您想要的:
public static IEnumerable<string> GetFiles(
string rootDirectory,
Func<string, bool> directoryFilter,
string filePattern)
{
foreach (string matchedFile in Directory.GetFiles(rootDirectory, filePattern, SearchOption.TopDirectoryOnly))
{
yield return matchedFile;
}
var matchedDirectories = Directory.GetDirectories(rootDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Where(directoryFilter);
foreach (var dir in matchedDirectories)
{
foreach (var file in GetFiles(dir, directoryFilter, filePattern))
{
yield return file;
}
}
}
你会这样使用它:
var files = GetFiles("C:\\SearchDirectory", d => !d.Contains("AvoidMe", StringComparison.OrdinalIgnoreCase), "*.*");
为什么会增加复杂性?这种方法完全避免在您不感兴趣的目录中查找。顾名思义,SearchOption.AllDirectories 将在所有中搜索目录。
如果您不熟悉迭代器方法(yield return 语法),可以用不同的方式编写:问吧!
另类
这有几乎相同的效果。但是,它仍然会在您要忽略的目录的子目录中找到文件。也许这对你没问题;代码更容易理解。
public static IEnumerable<string> GetFilesLinq(
string root,
Func<string, bool> directoryFilter,
string filePattern)
{
var directories = Directory.GetDirectories(root, "*.*", SearchOption.AllDirectories)
.Where(directoryFilter);
List<string> results = new List<string>();
foreach (var d in directories)
{
results.AddRange(Directory.GetFiles(d, filePattern, SearchOption.TopDirectoryOnly));
}
return results;
}