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);
   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);
     }
    }
   }
}
treeView1.EndUpdate();
}

界面截图:



    测试一下,在我的电脑上遍历所有磁盘上的文件用了25秒,看来效果还不错!试着把与TreeView相关的操作去除,只是简单的遍历所有文件,再测用了10.2秒,共计402786个目录和文件,看来主要功夫都花在维护TreeView的结构上。测试代码如下:

private void button1_Click(object sender, EventArgs e)
{
DateTime begin = DateTime.Now;
BuildTree();
DateTime end = DateTime.Now;
TimeSpan time = end.Subtract(begin);
MessageBox.Show(time.TotalSeconds.ToString());
}

算法真是个好东西,奇妙无穷啊!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值