C# 如何循环遍历所有目录中的所有文件并仅获取文件类型?
在这个方法中,如果我没有弄错的话,它是在文件内部搜索。 所以当我输入searchTerm例如“Form1”时,它找到了46个文件 但是现在我想在不使用searchTerm的情况下更改方法,这样它将遍历所有文件,但最后我想得到所有文件类型的列表。如果有相同的副本,请不要将它们添加到列表中,这样最后我将得到一个包含文件类型项目的列表,如:cs、txt、xml,这样我就知道有哪些文件类型C# 如何循环遍历所有目录中的所有文件并仅获取文件类型?,c#,.net,winforms,C#,.net,Winforms,在这个方法中,如果我没有弄错的话,它是在文件内部搜索。 所以当我输入searchTerm例如“Form1”时,它找到了46个文件 但是现在我想在不使用searchTerm的情况下更改方法,这样它将遍历所有文件,但最后我想得到所有文件类型的列表。如果有相同的副本,请不要将它们添加到列表中,这样最后我将得到一个包含文件类型项目的列表,如:cs、txt、xml,这样我就知道有哪些文件类型 IEnumerable<string> SearchAccessibleFiles(string ro
IEnumerable<string> SearchAccessibleFiles(string root, string searchTerm)
{
var files = new List<string>();
foreach (var file in Directory.EnumerateFiles(root).Where(m => m.Contains(searchTerm)))
{
files.Add(file);
}
foreach (var subDir in Directory.EnumerateDirectories(root))
{
try
{
files.AddRange(SearchAccessibleFiles(subDir, searchTerm));
}
catch (UnauthorizedAccessException ex)
{
// ...
}
}
return files;
}
由于我没有找到一种方法在传递此目录时处理Directory.GetFiles,所以我尝试使用递归方法。您可以使用
extension=Path.GetExtension(fileName)获取文件扩展名使用文件列表上的和
删除重复项,如下所示:
IEnumerable<string> SearchAccessibleFiles(string root, string searchTerm)
{
var files = new List<string>();
foreach (var file in Directory.EnumerateFiles(root).Where(m => m.Contains(searchTerm)))
{
string extension = Path.GetExtension(file);
files.Add(extension);
}
foreach (var subDir in Directory.EnumerateDirectories(root))
{
try
{
files.AddRange(SearchAccessibleFiles(subDir, searchTerm));
}
catch (UnauthorizedAccessException ex)
{
// ...
}
}
return files.Distinct().ToList();
}
var extensionsList = SearchAccessibleFilesNoDistinct("rootAddress",null);
第一次打电话是这样的:
IEnumerable<string> SearchAccessibleFiles(string root, string searchTerm)
{
var files = new List<string>();
foreach (var file in Directory.EnumerateFiles(root).Where(m => m.Contains(searchTerm)))
{
string extension = Path.GetExtension(file);
files.Add(extension);
}
foreach (var subDir in Directory.EnumerateDirectories(root))
{
try
{
files.AddRange(SearchAccessibleFiles(subDir, searchTerm));
}
catch (UnauthorizedAccessException ex)
{
// ...
}
}
return files.Distinct().ToList();
}
var extensionsList = SearchAccessibleFilesNoDistinct("rootAddress",null);
您可以看到,我通过递归方法传递了文件列表,通过这种方法,我们在所有递归调用中都有相同的文件列表,因此应该做到这一点,请记住,在递归调用中,不需要获取返回的列表,因为我们已经有了相同的列表,但最终我们可以使用返回的列表以供进一步使用。
希望有帮助问题可以分解为几个部分:
(1) 递归枚举所有可访问的目录
(2) 枚举多个目录文件
(3) 获取不同的文件扩展名
请注意,只有(3)是特定的,(1)和(2)是通用的,可以用于其他处理(如SearchAccessibleFiles
等)。因此,让我们分别解决它们:
(1)递归枚举所有可访问的目录:
这又可以分为两部分:
(A) 递归枚举泛型树结构
(B) 上述可访问目录树的专门化
对于(A)我个人使用我的答案中的helper方法和类似方法:
public static class TreeUtils
{
public static IEnumerable<T> Expand<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector)
{
var stack = new Stack<IEnumerator<T>>();
var e = source.GetEnumerator();
try
{
while (true)
{
while (e.MoveNext())
{
var item = e.Current;
yield return item;
var elements = elementSelector(item);
if (elements == null) continue;
stack.Push(e);
e = elements.GetEnumerator();
}
if (stack.Count == 0) break;
e.Dispose();
e = stack.Pop();
}
}
finally
{
e.Dispose();
while (stack.Count != 0) stack.Pop().Dispose();
}
}
}
最后,仅供比较,以下是使用相同帮助程序时原始方法的外观:
IEnumerable<string> SearchAccessibleFiles(string root, string searchTerm)
{
return DirectoryUtils.EnumerateAccessibleFiles(rootPath, true)
.Where(file => file.FullName.Contains(searchTerm))
.Select(file => file.FullName);
}
IEnumerable searchAccessibleFile(字符串根,字符串searchTerm)
{
返回DirectoryUtils.EnumerateAccessibleFiles(根路径,true)
.Where(file=>file.FullName.Contains(searchTerm))
.Select(file=>file.FullName);
}
如果搜索词不应包含目录信息,则可以将筛选条件更改为file.Name.Contains(搜索词)
工作很好。我添加了一个问题,这样它就不会添加重复的扩展名:if(!files.Contains(extension)),就在files.add(extension)行之前;但我最终还是看到了重复的扩展。为什么它一直在添加重复项?@code>searchassiblefiles
递归调用searchassiblefiles
,每次调用searchassiblefiles
时都会创建一个与作用域相关的files
列表的新实例,作为回报,您将添加这个列表usnigfiles.AddRange
。所以如果(!files.Contains(extension))
只处理该目录中的重复文件,而不是上层目录或子目录。@。我无法将列表实例从函数中取出。不确定。
partial class DirectoryUtils
{
public static IEnumerable<FileInfo> EnumerateAccessibleFiles(string path, bool allDirectories = false)
{
return EnumerateAccessibleDirectories(path, allDirectories).EnumerateFiles();
}
public static IEnumerable<FileInfo> EnumerateFiles(this IEnumerable<DirectoryInfo> source)
{
return source.SelectMany(di => di.EnumerateFiles());
}
}
var result = DirectoryUtils.EnumerateAccessibleFiles(rootPath, true)
.Select(file => file.Extension).Distinct()
.ToList();
IEnumerable<string> SearchAccessibleFiles(string root, string searchTerm)
{
return DirectoryUtils.EnumerateAccessibleFiles(rootPath, true)
.Where(file => file.FullName.Contains(searchTerm))
.Select(file => file.FullName);
}