我正在使用此代码
private IEnumerable<String> FindAccessableFiles(string path, string file_pattern, bool recurse)
{
IEnumerable<String> emptyList = new string[0];
if (File.Exists(path))
return new string[] { path };
if (!Directory.Exists(path))
return emptyList;
var top_directory = new DirectoryInfo(path);
// Enumerate the files just in the top directory.
var files = top_directory.EnumerateFiles(file_pattern);
var filesLength = files.Count();
var filesList = Enumerable
.Range(0, filesLength)
.Select(i =>
{
string filename = null;
try
{
var file = files.ElementAt(i);
filename = file.FullName;
}
catch (UnauthorizedAccessException)
{
}
catch (InvalidOperationException)
{
// ran out of entries
}
return filename;
})
.Where(i => null != i);
if (!recurse)
return filesList;
var dirs = top_directory.EnumerateDirectories("*");
var dirsLength = dirs.Count();
var dirsList = Enumerable
.Range(0, dirsLength)
.SelectMany(i =>
{
string dirname = null;
try
{
var dir = dirs.ElementAt(i);
dirname = dir.FullName;
return FindAccessableFiles(dirname, file_pattern, recurse);
}
catch (UnauthorizedAccessException)
{
}
catch (InvalidOperationException)
{
// ran out of entries
}
return emptyList;
});
return Enumerable.Concat(filesList, dirsList);
}
我在遍历包含超过 100k 个文件的文件夹时遇到了一些性能问题 - 当我枚举它们时,我忽略了所有图像。
我正在尝试弄清楚如何将它们从枚举列表中排除,这样它们就不会首先被处理,但无法弄清楚如何做到这一点。
我有一个List<String>
我想排除并在代码中使用 Contains
执行此操作.
如果我将它们排除在 FindAccessableFiles
之外,我会获得性能提升吗?首先,我该怎么做?我最初的尝试是,如果文件扩展名包含在扩展名列表中,则抛出异常,但我确信这不是最好的方法。
FindAccessableFiles
的目的是生成一个文件列表来规避 GetFiles()
的问题尝试访问引发权限错误的文件时引发异常。
最佳答案
部分问题在于 FindAccessableFiles
返回 IEnumerable<string>
每次枚举时都会重新遍历整个目录结构的实例。 Select
和Where
每次遍历枚举时都会重新评估子句,因此您将多次重复这项昂贵的工作。解决此问题的一个快速解决方法是通过调用 .ToList
强制步行一次关于返回值
return Enumerable.Concat(filesList, dirsList).ToList();
请注意,这将导致此时立即遍历整个枚举。然而,它只会进行一次。
如果您仍然遇到性能问题,您应该考虑一些其他选项
- 您提到有些图像您会忽略。在访问磁盘以获取有关它们的信息之前,我会过滤掉它们。访问磁盘比检查路径名要昂贵得多
- 将磁盘移动到后台线程
关于c# - 使用 Enumerable 和 Lambda 过滤文件列表并删除不需要的扩展名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18360562/