如何将文件名列表转换为树结构?

Jak*_*les 6 c# tree

我有一些文件路径的字符串数组:

path/to/folder/file.xxx
path/to/other/
path/to/file/file.xx
path/file.x
path/
Run Code Online (Sandbox Code Playgroud)

如何将此列表转换为树结构?到目前为止,我有以下内容:

/// <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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我只是有点不知道如何实际分割路径和所有.以/结尾的任何路径都是一个目录,任何一个没有的路径都不是.

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

例如,如果我有输入:

path/to/file.c
path/file.c
path/
Run Code Online (Sandbox Code Playgroud)

我如何解释path/to/输入中没有的事实?

com*_*ech 7

这是一个生成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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用上述内容,请创建一个新集合:

        NodeEntryCollection cItems = new NodeEntryCollection();
Run Code Online (Sandbox Code Playgroud)

然后,对于列表中的每一行:

        cItems.AddEntry(sLine, 0);
Run Code Online (Sandbox Code Playgroud)