我正在使用此代码
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()
抛出异常试图访问导致权限错误的文件的问题。
答案 0 :(得分:2)
部分问题是FindAccessableFiles
正在返回一个IEnumerable<string>
实例,每次枚举时都会重新遍历整个目录结构。每次进行枚举时都会重新评估Select
和Where
子句,因此您需要多次重复这项昂贵的工作。一个快速解决方法是通过在返回值
.ToList
来强制步行一次
return Enumerable.Concat(filesList, dirsList).ToList();
请注意,这将导致此时立即遍历整个枚举。但是它只会完成一次。
如果您仍然看到性能问题,还应考虑其他一些选项
答案 1 :(得分:1)
我同意JaredPar,你想确保你不重新枚举。您的返回应该有.ToList(),但var files = top_directory.EnumerateFiles(file_pattern);
也需要它。
异常处理非常昂贵,因此不建议添加超过您的内容。枚举文件不支持您正在寻找的那种过滤,因此您最终必须在某处手动执行此操作,可能最好这样做:
filename = excludedExtensionList.Any(e => e == file.Extension) ? null : file.FullName;
如果仍然存在性能问题,则必须考虑如何将操作分解为更小的块:如果文件名可靠,您可能会想出一个方案来更改EnumerateFiles pattern(所有文件以“a”开头,然后是“b”,然后是“c”等)。或者如果在同一个文件夹中存在大量垃圾,是否可以更改目录结构,以使不需要的文件始终位于您知道要忽略的子文件夹中?