文件/文件夹结构的递归搜索

3
我正在尝试为一个Web服务构建一个递归搜索函数,以返回文件和文件夹列表。我创建了两个方法使它们作为递归搜索,首先获取顶层内容,然后将任何文件添加到fileList,将任何子文件夹添加到subFoldersList中。我们传入访问级别(在我们的情况下是root),然后是您想要信息的路径。如果找到任何文件夹,则删除顶部文件夹,因为已经开始搜索该文件夹。然后调用processDirectories方法,它将新的路径位置传回getFiles,从而再次启动整个过程。现在进行测试时,我的文件夹结构如下。当它尝试将第二个文件(profilepic.png)添加到列表中时,出现错误“集合已修改;枚举操作无法执行。” 这个错误是什么原因造成的?
Photos
    picture1.png
    TestFolder
        profilepic.png

我的代码:

    public static List<string> fileList = new List<string>();
    public static List<string> subFolderList = new List<string>();

    static void processDirectories(string access, string Folder)
    {
        getFiles(access, Folder);
    }

    static void getFiles(string access, string Folder)
    {
        var accessToken = new OAuthToken(token, secret);
        var api = new DssAPI(ConsumerKey, ConsumerSecret, accessToken);
        var folder = api.GetContents(access, Folder);//Get list from WebService

        foreach (var item in folder.Contents)//Contents is an IEnumerable
        {
            if (item.IsDirectory == true)
                subFolderList.Add(item.Path);
            else
                fileList.Add(item.Path);
        }

        foreach (var subFolder in subFolderList)
        {
            subFolderList.RemoveAt(0);
            processDirectories(root, subFolder);
        }

    }
5个回答

4
假设这不是一项学术任务,您可以使用Directory.EnumerateFiles来避免自己实现这个功能。
foreach(var png in Directory.EnumerateFiles(sourceDirectory, "*.png", SearchOption.AllDirectories))
{
   // do something with the png file
}

Directory.EnumerateFiles也很好,因为它返回一个枚举器。您可以开始迭代它,如果您想要提前退出(例如,只需要显示前20个匹配的文件),则可以这样做,并且不会迭代所有目录中的文件。 - Sami Kuhmonen

2
改变这个:
foreach (var subFolder in subFolderList)
{
    subFolderList.RemoveAt(0);
    processDirectories(root, subFolder);
}

致:

while (subFolderList.Count > 0)
{
    var subFolder = subFolderList[0];
    subFolderList.RemoveAt(0);
    processDirectories(root, subFolder);
}

在迭代集合时,不能修改它,因此当你使用foreach循环并在迭代中删除其中的项时,会导致麻烦。解决方法通常是使用for循环并适当地操纵循环变量,但在您的情况下,使用while循环更简单。


1

问题出在这里

    foreach (var subFolder in subFolderList)
    {
        subFolderList.RemoveAt(0);
        processDirectories(root, subFolder);
    }

你正在遍历 subFilderList,并同时从中删除项目。机器不知道如何处理这种情况。
在这种情况下,我建议使用常规的 for 循环。

1

试试这个,

Public static void GetFilesLocal( string path)
{
    foreach (string f in Directory.GetFiles( path))
    {
        // Add to subFolderList.
    }
    foreach (string d in Directory.GetDirectories( path))
    {
        GetFilesLocal( d ); 
    }
}

你会在哪里将文件添加到文件列表中,以便与它们所属的子文件夹保持同步? - user1732364

0

正如错误信息所说,您不能遍历集合并对其进行修改。例如,较低的foreach正在迭代subFolderList,然后您删除第一个项目。之后,迭代器无效。

如果要修改集合,则应使用for循环,但是如果删除第一个项目等,则必须记住减少索引变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接