【问题标题】:Issues with tail recursion in file operations(C#)文件操作中的尾递归问题(C#)
【发布时间】:2016-12-18 18:16:27
【问题描述】:

我正在编写一个程序来查找计算机上某种类型的所有文件(当前是图像文件),并且我正在使用尾递归以这种方式搜索目录:

private void ImageSearchByDir(DirectoryInfo dir)
{
     //search for images by directory, later display them with this method when I get basic search working
     foreach (var f in dir.GetFiles())
     {
         //add file info to current list
         this.myfiles.Add(f);
     }

     foreach (var d in dir.GetDirectories())
     {
         //recursive call to iterate through subdirectories
         ImageSearchByDir(d);
     }
}

在搜索包含大量文件的目录时似乎会出现此问题。例如,我搜索了一个文件夹,其中包含约 700 张图像,这些图像位于 3 级文件夹下,没有问题,但尝试搜索我的桌面会使程序崩溃。我认为这与递归和产生的堆栈大小有关,如果可能的话,我想实现一个更优雅的解决方案(我已经阅读了蹦床,但我不能 100% 确定会解决这个问题)。

【问题讨论】:

  • 1) 你收到了什么样的异常? 2) 可能只收集文件名作为string,而不是FileInfo
  • 您正在做的是递归,但不符合尾递归的条件。尾递归要求在调用自身后函数中没有额外的操作。在您的情况下,foreach 循环必须在每次递归调用后运行其检查更多项目,从而使此非尾递归。 Luiso 的回答提供了一种完全无需递归的方法。
  • 回复Jackdaw我没有收到任何错误,程序只是停留在加载状态(白色背景,蓝色窗口加载圆圈光标,单击它会将其标记为“无响应”)。 Gideon 你说得很好,如果我的措辞具有误导性,请见谅。

标签: c# file recursion directory stack-overflow


【解决方案1】:

您可以使用Queue 并像这样完成您的工作:

class ImageSearcher
{
    private Queue<DirectoryInfo> found = new Queue<...>();

    public void ImageSearchByDir(DirectoryInfo dir)
    {
         found.Enqueue(dir);
         RealSearch();
    }

    private void RealSearch()
    {
         while(found.Count > 0)
         {
             var current = found.Dequeue()

             // do your filtering on the current folder

             // then add the children directories
             foreach(dir in current.GetDirectories())
             {
                 found.Enqueue(dir);
             }
         }  
    }
}

这样你就没有递归了,如果这就是你认为困扰你的地方

【讨论】:

  • 非常感谢,我会尽快为您更新。
  • 好消息是您的解决方案可以无缝融入我之前的代码。坏消息是我仍然有同样的问题,所以我要多玩一点。不过,使用队列似乎是一个很好的开始,我很感激向前推进。
  • 所以你的问题仍然存在,这意味着它与递归无关。根据@Jackdaw 的评论,您可以拥有Queue&lt;string&gt; 并使用System.IO.Directory.EnumerateDirectories..Enumerate.EnumerateFiles 使用该列表文件夹和文件,它们都采用string path
猜你喜欢
  • 2011-12-10
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
  • 2011-04-15
  • 1970-01-01
  • 2020-05-30
  • 1970-01-01
相关资源
最近更新 更多