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倍多。

你可能感兴趣的:(C#)