3

ファイルとフォルダーのリストを返す Web サービスの再帰的検索機能を構築しようとしています。再帰検索として機能するように 2 つのメソッドを作成しました。最初に最上位のコンテンツを取得して取得し、次に任意のファイルを fileList に追加し、任意のサブ フォルダーを subFoldersList に追加します。アクセス レベル (この場合はルート) を渡し、次に情報が必要なパスを渡します。フォルダが見つかった場合は、そのフォルダの検索が開始されているため、最上位のフォルダが削除されます。次に、processDirectories メソッドを呼び出します。このメソッドは、プロセスを最初からやり直す新しいパスの場所を getFiles に返します。今、私のフォルダ構造をテストするために、以下に示します。2 番目のファイル (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);
        }

    }
4

5 に答える 5

4

これを学術的な演習として書いているのではないと仮定すると、Directory.EnumerateFilesを使用して、これを自分で実装することを避けることができます。

foreach(var png in Directory.EnumerateFiles(sourceDirectory, "*.png", SearchOption.AllDirectories))
{
   // do something with the png file
}
于 2012-11-08T17:31:35.877 に答える
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 ループの方が簡単です。

于 2012-11-08T17:31:49.963 に答える
1

問題はここにあります

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

を繰り返し処理しsubFilderListていて、同時にそこからアイテムを削除しています。マシンはそれを処理する方法を知りません。

この場合、私が提案するのは、おそらく通常のforループを行うことです

于 2012-11-08T17:31:19.013 に答える
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 ); 
    }
}
于 2012-11-08T17:31:57.490 に答える
0

エラーメッセージが示すように、コレクションを調べて変更することはできません。たとえば、下の foreach は subFolderList を繰り返し処理してから、最初の項目を削除します。その後、反復子は無効になります。

コレクションを変更する場合は for ループを使用する必要がありますが、最初のアイテムなどを削除する場合は、インデクサー変数を減らすことを忘れないでください。

于 2012-11-08T17:32:59.430 に答える