0

指定されたパスにあるすべてのファイルとディレクトリをざっと検索するプログラムを作成しています。したがって、そのノードがたまたまディレクトリである場合、1 つのノードに他のノードが存在する可能性があります。

これが私のNodeクラスです:

class Node
{
    public List<Node> Children = new List<Node>(); // if node is directory then children will be the files and directories in this direcotry
    public FileSystemInfo Value { get; set; }  // can eather be a FileInfo or DirectoryInfo

    public bool IsDirectory 
    { 
        get{ return Value is DirectoryInfo;} 
    }

    public long Size   // HERE IS WHERE I AM HAVING PROBLEMS! I NEED TO RETRIEVE THE 
    {                  // SIZE OF DIRECTORIES AS WELL AS FOR FILES.
        get
        {
            long sum = 0;

            if (Value is FileInfo)
                sum += ((FileInfo)Value).Length;
            else
                sum += Children.Sum(x => x.Size);

            return sum;
        }
    }

    // this is the method I use to filter results in the tree
    public Node Search(Func<Node, bool> predicate)
    {
         // if node is a leaf
         if(this.Children.Count==0)
         {
             if (predicate(this))
                return this;
             else
                return null;
         }
         else // Otherwise if node is not a leaf
         {
             var results = Children.Select(i => i.Search(predicate)).Where(i => i != null).ToList();

             if (results.Any()) // THIS IS HOW REMOVE AND RECUNSTRUCT THE TREE WITH A FILTER
             {
                var result = (Node)MemberwiseClone();
                result.Children = results;
                return result;
             }
             return null;
         }             
    }

}

そのノード クラスのおかげで、ツリーを次のように表示できます。

ここに画像の説明を入力

1 つの列にディレクトリまたはファイルの名前を表示し、右側にサイズを表示します。カンマがより明確に視覚化するのに役立つという理由だけで、サイズは通貨としてフォーマットされています.

だから今私の問題は、私がこのプログラムを持っている理由は、いくつかの事前検索を実行することでした。したがって、たとえば「.txt」拡張子を持つファイルのみを検索したい場合があります。ツリーでそのフィルターを実行すると、次のようになります。

ここに画像の説明を入力

(Node を受け取って bool を返す関数にテキストをコンパイルし、そのメソッドを Node クラスの Search メソッドに渡して、結果をフィルタリングすることに注意してください。コードを動的にコンパイルする方法の詳細については、次の URL を参照してください。http://www.codeproject.com/Articles/10324/Compiling-code-during-runtime )とにかく、この質問とは何の関係もありません。重要な部分は、その基準に一致しなかったすべてのノードを削除したことですand because I removed those nodes now the sizes of the directories changed!!!

したがって、私の質問は、ディレクトリの実際のサイズを維持しながら結果をフィルタリングするにはどうすればよいかということです。プロパティ Size を削除して、フィールドに置き換える必要があると思います。問題は、ツリーに追加するたびに、すべての親ディレクトリのサイズを更新する必要があり、複雑になることです。そのようにコーディングを開始する前に、クラスの実装を開始する方法についてご意見をお待ちしております。

4

1 に答える 1

2

再帰を使用しており、重みはノードレベルのプロパティであるため、ノードを削除した後でも合計が続くとは期待できません。それを上位レベル(コレクション)に昇格させるか、再帰内で外部カウンターを使用します(これはカウントされますが、フィルターに依存しないため、再帰を通じてこれを実行する必要があります)。

とにかく、なぜ .NET のコア機能を再度実装するのですか? フィルタリングや再帰検索以外の理由はありますか? どちらもBCL でかなりうまく実装されています。

于 2012-09-17T16:19:25.797 に答える