登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

从文件路径列表重建目录树  

2011-10-20 20:59:16|  分类: C# |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
    应用中经常需要一组文件路径及其目录树信息。除空文件夹外,文件路径中已经包含了所有的目录树信息。如能从一组文件路径中成功恢复出目录树,则不必再大动干戈同时保存文件路径和目录树两份信息了。

/// <summary>从文件路径建立目录树</summary>
public class PathTree : IEnumerable<KeyValuePair<string, PathTree>>
{
         private readonly SortedList<string, PathTree> children = new SortedList<string, PathTree>();

         
/// <summary>
将给定的键值序列添加到当前树中,各键值将作为各级子节点的值</summary>
         public PathTree AddFileName(IEnumerable<string> fileNameSegment)
         {
                   PathTree node = this;
                   foreach (var segment in fileNameSegment)
                   {
                            PathTree child;
                            if (node.children.TryGetValue(segment, out child) == false)
                            {
                                     child = new PathTree();
                                     node.children.Add(segment, child);
                            }
                            node = child;
                   }
                   return node;
         }

         #region GetFileNames
         /// <summary>得到所有的文件名列表</summary>
         public IEnumerable<IEnumerable<string>> GetFileNames()
         {
                   return GetFileNames(this);
         }
         /// <summary>得到给定目录下所有的文件名列表</summary>
         public IEnumerable<IEnumerable<string>> GetFileNames(IEnumerable<string> directorySegment)
         {
                   PathTree node = this;
                   foreach (var segment in directorySegment)
                   {
                            PathTree child;
                            if (node.children.TryGetValue(segment, out child) == false)
                                     return  Enumerable.Empty<IEnumerable<string>>();
                            node = child;
                   }
                   return GetFileNames(node);
         }
         /// <summary>得到给定节点的所有子节点的值</summary>
         private static IEnumerable<IEnumerable<string>> GetFileNames(PathTree root)
         {
                   foreach (var child in root.children)
                   {
                            var cur = new string[] { child.Key };
                            if (child.Value.children.Count == 0)
                                     yield return cur;
                            else
                            {
                                     var lower = GetFileNames(child.Value);
                                     foreach (var group in lower)
                                               yield return cur.Concat(group);
                            }
                   }
         }
         #endregion 

         #region IEnumerable
         public IEnumerator<KeyValuePair<string, PathTree>> GetEnumerator()
         {
                   return children.GetEnumerator();
         }
         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
         {
                   return this.GetEnumerator();
         }
         #endregion 

         #region XElement
         public IEnumerable<XElement> ToXElements()
         {
                   foreach (var child in children)
                            yield return new XElement("node", new XAttribute("value", child.Key), child.Value.ToXElements());
         }
         public override string ToString()
         {
                   return new XElement("tree", ToXElements()).ToString(SaveOptions.None);
         }
         #endregion
} 

例如目录列表:
dir1\dir1\file1
dir1\dir1\file2
dir1\dir2\file1
dir1\file1
dir1\file2
dir2\dir1
dir2
file1
PathTree处理后的目录树为:

<tree>
         <node value="dir1">
                   <node value="dir1">
                            <node value="file1" />
                            <node value="file2" />
                   </node>
                   <node value="dir2">
                            <node value="file1" />
                   </node>
                   <node value="file1" />
                   <node value="file2" />
         </node>
         <node value="dir2">
                   <node value="dir1" />
         </node>
         <node value="file1" />
</tree>

    通过GetFileNames方法重新展开的文件路径为:
dir1\dir1\file1
dir1\dir1\file2
dir1\dir2\file1
dir1\file1
dir1\file2
dir2\dir1
file1
    通过以上例子可发现:不是文件路径的目录路径会损失;空文件夹名也会被误解为文件名。因以上算法设计过程中只针对全部是文件路径的情况,所有不包含叶节点的路径都会损失,所有叶节点都认为是文件名。
    为避免文件路径分隔符“\”、“/”甚至“..”、"."等引入额外的复杂度,PathTree接口设计成路径中除分隔符之外的片段。如new PathTree().AddFileName("dir1\\dir1\\file1".Split('\\'))
    XML是表达树形数据结构非常自然的工具,故PathTree添加了ToXElements方法以将目录树转为XML DOMToString输出为XML的方式也很直观。
  评论这张
 
阅读(1645)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018