为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用“Directory.getFiles”获取磁盘上具有特定扩展名的所有文件并将它们

如何使用“Directory.getFiles”获取磁盘上具有特定扩展名的所有文件并将它们

C#
HUWWW 2023-08-13 16:00:54
我正在做一个控制台项目,其目标是在整个磁盘中搜索扩展名为“.config”的所有文件我尝试过类似的事情:foreach (string file in Directory.GetFiles("C:\\", "*.config", SearchOption.AllDirectories))  {   Console.WriteLine(file);   Console.ReadLine();}但给了我一个错误“拒绝访问路径(...)”。在互联网上我找到了这段代码:Stack<string> pending = new Stack<string>();        pending.Push("C:\\");        while (pending.Count != 0)        {            var path = pending.Pop();            string[] next = null;            try            {                next = Directory.GetFiles(path, "*.config");            }            catch { }            if (next != null && next.Length != 0)                foreach (var file in next)                {                    Console.WriteLine(file);                    Console.ReadLine();                }            try            {                next = Directory.GetDirectories(path);                foreach (var subdir in next) pending.Push(subdir);            }            catch { }        }但它只是显示始终单击“输入”的路径,我想将这些文件/路径保存在列表中。有人可以帮忙吗?
查看完整描述

3 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

您可以采取两件事来改进该代码:

  1. 使用Directory.EnumerateFiles()Directory.EnumerateDirectories()可以避免复制每个目录中所有文件的名称。

  2. 使方法的返回类型IEnumerable<string>更容易使用。

我们还需要非常小心由于尝试访问受保护的文件和目录而导致的异常。下面的代码也很复杂,因为您不允许在块yield return内部进行操作try/catch,因此我们必须稍微重新排列代码。

(另请注意,我们必须处置从 返回的枚举器.GetEnumerator();通常,当您使用 时,这是自动完成的foreach,但在这种情况下我们不能 - 因为必须避免yield return在 a 中执行try/catch- 所以我们必须使用 useusing来处置它。)

以下是对原始代码的修改:

public static IEnumerable<string> GetFiles(string root, string spec)

{

    var pending = new Stack<string>(new []{root});


    while (pending.Count > 0)

    {

        var path = pending.Pop();

        IEnumerator<string> fileIterator = null;


        try

        {

            fileIterator = Directory.EnumerateFiles(path, spec).GetEnumerator();

        }


        catch {}


        if (fileIterator != null)

        {

            using (fileIterator)

            {

                while (true)

                {

                    try

                    {

                        if (!fileIterator.MoveNext()) // Throws if file is not accessible.

                            break;

                    }


                    catch { break; }


                    yield return fileIterator.Current;

                }

            }

        }


        IEnumerator<string> dirIterator = null;


        try

        {

            dirIterator = Directory.EnumerateDirectories(path).GetEnumerator();

        }


        catch {}


        if (dirIterator != null)

        {

            using (dirIterator)

            {

                while (true)

                {

                    try

                    {

                        if (!dirIterator.MoveNext()) // Throws if directory is not accessible.

                            break;

                    }


                    catch { break; }


                    pending.Push(dirIterator.Current);

                }

            }

        }

    }

}

例如,以下是如何使用控制台应用程序列出“C:\”驱动器上所有可访问的“.txt”文件:


static void Main()

{

    foreach (var file in GetFiles("C:\\", "*.txt"))

    {

        Console.WriteLine(file);

    }

}


查看完整回答
反对 回复 2023-08-13
?
慕的地10843

TA贡献1785条经验 获得超8个赞

更换线路

Console.WriteLine(file);
Console.ReadLine();

用一种方法将它们存储在列表中。
例如

foundFiles.Add(file);

然后,当该方法完成时,您可以从此列表中读取所有找到的文件路径。

注意:
这不会产生系统上与过滤器匹配的所有文件。
只有您的应用程序有权访问其各自目录的文件才能通过这种方式找到。
例如,Windows目录和其他用户的用户目录通常受到保护。(假设您在 Windows 上运行)

请记住,某些文件可能会独立于其目录而受到保护。
因此,当尝试读取它们时,还要考虑读取可能会失败的事实。
只需用 try catch 包围读取即可。


查看完整回答
反对 回复 2023-08-13
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

关于错误“拒绝访问路径(...)”,有时您必须以管理员身份运行 Visual Studio 才能访问 C:\ 驱动器中的某些文件夹。



查看完整回答
反对 回复 2023-08-13
  • 3 回答
  • 0 关注
  • 115 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信