Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何循环遍历所有目录中的所有文件并仅获取文件类型?_C#_.net_Winforms - Fatal编程技术网

C# 如何循环遍历所有目录中的所有文件并仅获取文件类型?

C# 如何循环遍历所有目录中的所有文件并仅获取文件类型?,c#,.net,winforms,C#,.net,Winforms,在这个方法中,如果我没有弄错的话,它是在文件内部搜索。 所以当我输入searchTerm例如“Form1”时,它找到了46个文件 但是现在我想在不使用searchTerm的情况下更改方法,这样它将遍历所有文件,但最后我想得到所有文件类型的列表。如果有相同的副本,请不要将它们添加到列表中,这样最后我将得到一个包含文件类型项目的列表,如:cs、txt、xml,这样我就知道有哪些文件类型 IEnumerable<string> SearchAccessibleFiles(string ro

在这个方法中,如果我没有弄错的话,它是在文件内部搜索。 所以当我输入searchTerm例如“Form1”时,它找到了46个文件

但是现在我想在不使用searchTerm的情况下更改方法,这样它将遍历所有文件,但最后我想得到所有文件类型的列表。如果有相同的副本,请不要将它们添加到列表中,这样最后我将得到一个包含文件类型项目的列表,如:cs、txt、xml,这样我就知道有哪些文件类型

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
列表的新实例,作为回报,您将添加这个列表usnig
files.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);
}