0

我正在创建一个程序,可以草书查找指定路径中的所有文件和目录。因此,如果该节点恰好是一个目录,则该节点可能具有其他节点。

这是我的节点类:

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;
         }             
    }

}

并且由于该节点类,我能够将树显示为:

在此处输入图像描述

在一列中,我显示目录或文件的名称,并在右侧显示大小。大小被格式化为货币只是因为逗号有助于更清晰地可视化它。

所以现在我的问题是我有这个程序的原因是执行一些高级搜索。因此,我可能只想搜索具有“.txt”扩展名的文件。如果我在我的树上执行该过滤器,我将得到:

在此处输入图像描述

(请注意,我将文本编译为一个接受 Node 并返回 bool 的函数,并将该方法传递给 Node 类的 Search 方法以过滤结果。有关如何动态编译代码的更多信息,请参见: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 回答