如何从目录列表文件递归地填充树?

How to populate a tree recursively from a directory listing file?

我有一个 windows 目录的递归目录列表文件,如下所示。

 Volume in drive D is DATA
 Volume Serial Number is A4EC-104D

 Directory of D:\Studies\Projects\test

14/07/2019  08:09 PM    <DIR>          .
14/07/2019  08:09 PM    <DIR>          ..
14/07/2019  08:08 PM    <DIR>          Test1
               0 File(s)              0 bytes

 Directory of D:\Studies\Projects\test\Test1

14/07/2019  08:08 PM    <DIR>          .
14/07/2019  08:08 PM    <DIR>          ..
14/07/2019  08:08 PM    <DIR>          Test2
14/07/2019  08:08 PM    <DIR>          Test3
               0 File(s)              0 bytes

 Directory of D:\Studies\Projects\test\Test1\Test2

14/07/2019  08:08 PM    <DIR>          .
14/07/2019  08:08 PM    <DIR>          ..
14/07/2019  08:08 PM    <DIR>          Test4
               0 File(s)              0 bytes

 Directory of D:\Studies\Projects\test\Test1\Test2\Test4

14/07/2019  08:08 PM    <DIR>          .
14/07/2019  08:08 PM    <DIR>          ..
14/07/2019  08:08 PM                 0 testfile.txt
               1 File(s)              0 bytes

 Directory of D:\Studies\Projects\test\Test1\Test3

14/07/2019  08:08 PM    <DIR>          .
14/07/2019  08:08 PM    <DIR>          ..
14/07/2019  08:08 PM                 0 file2.txt
               1 File(s)              0 bytes

     Total Files Listed:
               2 File(s)              0 bytes
              14 Dir(s)  372,031,488,000 bytes free

我想从上面的文件中填充 TreeViewC#,它看起来应该类似于下图

我是编程新手,想获得一些有关如何解决此问题的提示。这是否需要任何递归函数调用?代码片段或伪代码解决方案会很棒。

尝试以下操作:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using System.Globalization;

namespace WindowsFormsApplication52
{
    public partial class Form1 : Form
    {
        const string FILENAME = @"c:\temp\test.txt";
        public Form1()
        {
            InitializeComponent();

            FILEITEM.ParseFile(FILENAME, this);

            FILEITEM.MakeTree(FILEITEM.files, null, treeView1, 0);

            treeView1.ExpandAll();

        }
    }
    public class FILEITEM
    {
        const string DIRECTORY_OF = "Directory of";
        const string REGEX_DATE_PATTERN = @"\d{2}/\d{2}/\d{4}\s\s\d{2}:\d{2}\s[AP]M";
        const string REGEX_FILENAME_PATTERN = @"[^\s]+";

        public static List<FILEITEM> files = new List<FILEITEM>();
        public string[] folder { get; set; }
        public string filename { get; set; }
        public DateTime time { get; set; }

        public static void ParseFile(string filename, Form1 form1)
        {
            CultureInfo info = CultureInfo.InvariantCulture;
            StreamReader reader = new StreamReader(filename);

            string[] directory = null;

            string line = "";
            while ((line = reader.ReadLine()) != null)
            {
                if (line.Contains(DIRECTORY_OF))
                {
                    directory = line.Substring(line.IndexOf(DIRECTORY_OF) + DIRECTORY_OF.Length).Trim().Split(new char[] {'\'}).ToArray();
                }
                else
                {
                    Match dateMatch = Regex.Match(line, REGEX_DATE_PATTERN);
                    if (dateMatch.Success && !line.Contains("<DIR>"))
                    {
                        Match filenameMatch = Regex.Match(line.Trim(), REGEX_FILENAME_PATTERN, RegexOptions.RightToLeft);
                        FILEITEM newFileItem = new FILEITEM() { folder = directory, filename = filenameMatch.Value, time = DateTime.ParseExact(dateMatch.Value, "dd/MM/yyyy  hh:mm tt", info) };
                        files.Add(newFileItem);
                    }
                }
            }

        }
        public static void MakeTree(List<FILEITEM> files, TreeNode node, TreeView treeview1, int index)
        {
            TreeNode childNode = null;
            var groups = files.Where(x => x.folder.Length > index).GroupBy(x => x.folder[index]).ToList();
            foreach(var group in groups)
            {
                childNode = new TreeNode(group.Key);
                if (node == null)
                {
                    treeview1.Nodes.Add(childNode);
                }
                else
                {
                    node.Nodes.Add(childNode);
                }
                foreach (FILEITEM item in group)
                {
                    if (item.folder.Length - 1 == index)
                    {
                        TreeNode fileNode = new TreeNode(string.Join(",", new string[] { item.filename, item.time.ToLongDateString() + "  " + item.time.ToLongTimeString() }));
                        childNode.Nodes.Add(fileNode);
                    }
                }
                MakeTree(group.ToList(), childNode, null, index + 1);
            }
        }

    }
}