2011-12-23 57 views
5

我有一些文件的路径字符串数组:如何将文件名列表转换为树结构?

path/to/folder/file.xxx 
path/to/other/ 
path/to/file/file.xx 
path/file.x 
path/ 

我怎么能这个列表转换为树型结构?到目前为止,我有以下几点:

/// <summary> 
/// Enumerates types of filesystem nodes. 
/// </summary> 
public enum FilesystemNodeType 
{ 
    /// <summary> 
    /// Indicates that the node is a file. 
    /// </summary> 
    File, 

    /// <summary> 
    /// Indicates that the node is a folder. 
    /// </summary> 
    Folder 
} 

/// <summary> 
/// Represents a file or folder node. 
/// </summary> 
public class FilesystemNode 
{ 
    private readonly ICollection<FilesystemNode> _children; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="FilesystemNode"/> class. 
    /// </summary> 
    public FilesystemNode() 
    { 
     _children = new LinkedList<FilesystemNode>(); 
    } 

    /// <summary> 
    /// Gets or sets the name of the file or folder. 
    /// </summary> 
    public string Name { get; set; } 

    /// <summary> 
    /// Gets or sets the full path to the file or folder from the root. 
    /// </summary> 
    public string Path { get; set; } 

    /// <summary> 
    /// Gets or sets a value indicating whether the node is a file or folder. 
    /// </summary> 
    public FilesystemNodeType Type { get; set; } 

    /// <summary> 
    /// Gets a list of child nodes of this node. The node type must be a folder to have children. 
    /// </summary> 
    public ICollection<FilesystemNode> Children 
    { 
     get 
     { 
      if (Type == FilesystemNodeType.Folder) 
       return _children; 

      throw new InvalidOperationException("File nodes cannot have children"); 
     } 
    } 
} 

我只是有点在如何实际分割的路径和所有的损失。以/结尾的任何路径都不是。

此外,虽然我的输入将始终包含文件夹的路径,但如果没有,我该如何解释这种情况?

举例来说,如果我有输入:

path/to/file.c 
path/file.c 
path/ 

我将如何解释这一事实path/to/是不是在输入?

回答

5

这里是产生的NodeEntry项目嵌套的字典中的溶液(您可以根据需要替换文件信息类):

public class NodeEntry 
{ 
    public NodeEntry() 
    { 
     this.Children = new NodeEntryCollection(); 
    } 

    public string Key { get; set; } 
    public NodeEntryCollection Children { get; set; } 

} 

public class NodeEntryCollection : Dictionary<string, NodeEntry> 
{ 
    public void AddEntry(string sEntry, int wBegIndex) 
    { 
     if (wBegIndex < sEntry.Length) 
     { 
      string sKey; 
      int wEndIndex; 

      wEndIndex = sEntry.IndexOf("/", wBegIndex); 
      if (wEndIndex == -1) 
      { 
       wEndIndex = sEntry.Length; 
      } 
      sKey = sEntry.Substring(wBegIndex, wEndIndex - wBegIndex); 
      if (!string.IsNullOrEmpty(sKey)) { 
       NodeEntry oItem; 

       if (this.ContainsKey(sKey)) { 
        oItem = this[sKey]; 
       } else { 
        oItem = new NodeEntry(); 
        oItem.Key = sKey; 
        this.Add(sKey, oItem); 
       } 
       // Now add the rest to the new item's children 
       oItem.Children.AddEntry(sEntry, wEndIndex + 1); 
      } 
     } 
    } 
} 

使用上面,创建一个新的集合:

 NodeEntryCollection cItems = new NodeEntryCollection(); 

那么,对于您的列表中的每一行:

 cItems.AddEntry(sLine, 0); 
+0

这让我我需要的地方,非常感谢你多! – 2011-12-24 02:48:36

+0

这里添加的主要内容:https://gist.github.com/2282389(为了您的方便) – 2012-04-02 10:20:14

+0

如何从子节点中选择子节点,例如如何从'子目录'中的子目录中获取子目录'directory1/subdirectory/files' ? – 2017-08-08 11:00:11

0

'/'字符分割每行。如果字符串数组的长度是5,那么前四个项目应该是目录,你必须测试的最后延期:

string.IsNullOrEmpty(new FileInfo("test").Extension) 

如果像你的情况,总是即使是'/'最后一个目录,那么分割字符串数组的最后一项是空的。

其余的只是穿过你的树。解析项目时,检查第一个目录是否存在于根节点的Children属性中。如果它不存在,请添加它,如果它存在,请使用这个并继续。