2011-12-23 59 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屬性中。如果它不存在,請添加它,如果它存在,請使用這個並繼續。