zoukankan      html  css  js  c++  java
  • C# 使用栈遍历磁盘文件和目录,非传统递归方法。

        序:前不久使用DEV的TreeList控件,需要根据输入内容定位到对应的节点,由于树的层数不确定,先前采用递归算法遍历Tree,但总觉得别扭,个人比较反感递归函数,好比一个脱缰的野马,难以控制。理论上说,所有递归算法都可以转换为非递归算法,因此决定不使用递归,上网搜了一些资料,最终成功搞定。

        遍历硬盘文件的方法与TreeList是相似的,核心所在就是使用“栈stack”这个数据结构,先把所有驱动器压栈,比如C、D、E、F、G。然后依次遍历每个驱动器,如G:\,先将其出栈,获取该目录下的所有子目录和子文件,将子目录逐个压栈,子文件直接处理。这样处理后,位于栈顶的就是子目录,它里面包含的还有内容,将栈顶目录出栈,再获取该目录下的所有子目录和子文件,同样再将子目录压栈,如此重复,最终实现所有目录和文件的遍历。

        来点实现的代码吧,在Form上拖放一个TreeView、ImageList,其中ImageList有3个图标,分别用于代表磁盘、文件夹、文件。

            /// <summary>
            /// 生成目录树
            /// </summary>
            private void BuildTree()
            {
                //设置图像列表,并暂停重绘
                treeView1.ImageList = imageList1;
                treeView1.BeginUpdate();
                //存放树节点的栈
                Stack<TreeNode> skNode = new Stack<TreeNode>();
                int imageIndex = 0;
                //添加磁盘列表
                string[] drives = Directory.GetLogicalDrives();
                for (int i = 0; i < drives.Length; i++)
                {
                    //每个节点的Text存放目录名,Name存放全路径
                    TreeNode node = new TreeNode(drives[i], 0, 0);
                    node.Name = drives[i];
                    treeView1.Nodes.Add(node);
                    skNode.Push(node);
                }
                while (skNode.Count > 0)
                {
                    //弹出栈顶目录,并获取路径
                    TreeNode curNode = skNode.Pop();
                    string path = curNode.Name;
    
                    FileInfo fInfo = new FileInfo(path);
                    try
                    {
                        if ((fInfo.Attributes & FileAttributes.Directory) != 0)
                        {
                            string[] subDirs = null;
                            string[] subFiles = null;
                            try
                            {
                                //获取当前目录下的所有子目录和文件
                                subDirs = Directory.GetDirectories(path);
                                subFiles = Directory.GetFiles(path);
                            }
                            catch
                            { }
                            if (subDirs != null && subFiles != null)
                            {
                                //目录入栈
                                imageIndex = 1;
                                for (int i = 0; i < subDirs.Length; i++)
                                {
                                    string dirName = Path.GetFileName(subDirs[i]);
                                    TreeNode dirNode = new TreeNode(dirName, 1, 1);
                                    dirNode.Name = subDirs[i];
                                    curNode.Nodes.Add(dirNode);
                                    skNode.Push(dirNode);
                                }
                                //文件无需入栈
                                imageIndex = 2;
                                for (int i = 0; i < subFiles.Length; i++)
                                {
                                    string fileName = Path.GetFileName(subFiles[i]);
                                    curNode.Nodes.Add(subFiles[i], fileName, 2);
                                }
                            }
                        }
                    }
                    catch { }
                }
                treeView1.EndUpdate();
            }

    虽然效率不是很明显,但是如果去除维护treeview的话,效率会提升1倍多。

  • 相关阅读:
    软件工程实践2019第四次作业
    软件工程实践2019第三次作业
    C语言第九次博客作业---指针
    基于open cv的人脸检测功能 (大自然的搬运工)
    STM32F103RCT6驱动AD7705(cubeide)
    python-tips
    在树莓派上使用DS18B02,并将数据打印在oled上
    数据库基础1
    转载:Why machine learning algorithms are hard to tune and how to fix it
    论文笔记(7)-"Local Newton: Reducing Communication Bottleneck for Distributed Learning"
  • 原文地址:https://www.cnblogs.com/StupidsCat/p/2847473.html
Copyright © 2011-2022 走看看