转载请注明来源:http://www.cnblogs.com/xuesongshu

要点:

1、搜索的顶层目录在进入循环之前进栈

2、栈元素存储字符串指针,出栈时释放资源

3、每次循环开始,栈顶元素出栈

4、在遍历一个文件夹时,遇到子文件夹则进栈

5、外层循环以堆栈是否为空为标志,内层循环以FindNextFile返回值为标志

6、本搜索算法适用于按关键字搜索,当文件夹名称符合搜索条件时文件夹作为搜索结果通知调用者,不会入栈。

7、回调函数地址使用long型传递

8、本程序功能是批量增加、修改或者删除指定文件夹下所有文件前缀,附带遍历功能。在参照流程图编写实现代码时与流程图所画逻辑会稍有出入。

流程图如下:

需要引入的头文件:

  1. #include <stack>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <list>
  5. #include <set>

  

回调函数定义:

  1. typedef HRESULT (__stdcall *XCallbackMethodType)(HWND,BSTR,int);

  

实现代码如下:

  1. STDMETHODIMP CFileTool::SearchFiles(BSTR topDirectoryName, BSTR key, HWND mainWnd,long callbackAddress)
  2. {
  3. HINSTANCE dllInst=(HINSTANCE)GetModuleHandle(L"xssfj.dll");
  4.  
  5. WCHAR finishedMsg[256]={0};
  6. LoadString(dllInst,IDS_FILE_DELETESPECIFY_SEARCHSUCCESS,finishedMsg,256);
  7. XCallbackMethodType callbackMsg=(XCallbackMethodType)callbackAddress;
  8. DWORD attribute=GetFileAttributesW(topDirectoryName);
  9. if(!(attribute&FILE_ATTRIBUTE_DIRECTORY))
  10. return E_INVALIDARG;
  11. if(!callbackMsg)
  12. return E_INVALIDARG;
  13. if(StrStrI(topDirectoryName,key))
  14. {
  15. callbackMsg(mainWnd,topDirectoryName,2);
  16. callbackMsg(mainWnd,finishedMsg,0);
  17. return S_OK;
  18. }
  19. std::stack<WCHAR*> directoryNameStack;
  20. WCHAR* tmpStackData=(WCHAR*)calloc(MAX_PATH,sizeof(WCHAR));
  21. lstrcpyW(tmpStackData,topDirectoryName);
  22. directoryNameStack.push(tmpStackData);
  23. while(!directoryNameStack.empty())
  24. {
  25. WCHAR* currentDirName=directoryNameStack.top();
  26. directoryNameStack.pop();
  27. callbackMsg(mainWnd,currentDirName,1);
  28. WCHAR tmpParentPath[MAX_PATH]={0};
  29. lstrcpy(tmpParentPath,currentDirName);
  30. if(currentDirName[lstrlen(currentDirName)-1]!='\\')
  31. {
  32. lstrcat(tmpParentPath,L"\\");
  33. lstrcat(currentDirName,L"\\*.*");
  34. }
  35. else
  36. lstrcat(currentDirName,L"*.*");
  37. WIN32_FIND_DATA meiju={0};
  38.  
  39. HANDLE tmpHandle=FindFirstFile(currentDirName,&meiju);
  40. if(tmpHandle!=INVALID_HANDLE_VALUE&&tmpHandle)
  41. {
  42. if(lstrcmpW(meiju.cFileName,L".")!=0&&lstrcmpW(meiju.cFileName,L"..")!=0)
  43. {
  44. if(StrStrI(meiju.cFileName,key))
  45. {
  46. WCHAR tmpFsObj[MAX_PATH]={0};
  47. lstrcpyW(tmpFsObj,tmpParentPath);
  48. lstrcat(tmpFsObj,meiju.cFileName);
  49. callbackMsg(mainWnd,tmpFsObj,2);
  50. }
  51. }
  52. do
  53. {
  54. DWORD tmpFileResult=FindNextFile(tmpHandle,&meiju);
  55. if(tmpFileResult==ERROR_NO_MORE_FILES||tmpFileResult==0)
  56. break;
  57. if(lstrcmpW(meiju.cFileName,L".")==0||lstrcmpW(meiju.cFileName,L"..")==0)
  58. continue;
  59. if(StrStrI(meiju.cFileName,key))
  60. {
  61. WCHAR tmpFsObj[MAX_PATH]={0};
  62. lstrcpyW(tmpFsObj,tmpParentPath);
  63. lstrcat(tmpFsObj,meiju.cFileName);
  64. callbackMsg(mainWnd,tmpFsObj,2);
  65. }
  66. else
  67. {
  68. WCHAR tmpFsobjPath[MAX_PATH]={0};
  69. lstrcpy(tmpFsobjPath,tmpParentPath);
  70. lstrcat(tmpFsobjPath,meiju.cFileName);
  71. callbackMsg(mainWnd,tmpFsobjPath,1);
  72. DWORD tmpFileAttribute=GetFileAttributes(tmpFsobjPath);
  73. if(tmpFileAttribute&FILE_ATTRIBUTE_DIRECTORY)
  74. {
  75. WCHAR* tmpData=(WCHAR*)calloc(MAX_PATH,sizeof(WCHAR));
  76. lstrcpy(tmpData,tmpFsobjPath);
  77. directoryNameStack.push(tmpData);
  78. }
  79. }
  80. }
  81. while(true);
  82. FindClose(tmpHandle);
  83. }
  84. free(currentDirName);
  85. }
  86. callbackMsg(mainWnd,finishedMsg,0);
  87. return S_OK;
  88. }

  

Win32非递归遍历和搜索文件以及目录算法的更多相关文章

  1. 二叉树3种递归和非递归遍历(Java)

    import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...

  2. C++编程练习(17)----“二叉树非递归遍历的实现“

    二叉树的非递归遍历 最近看书上说道要掌握二叉树遍历的6种编写方式,之前只用递归方式编写过,这次就用非递归方式编写试一试. C++编程练习(8)----“二叉树的建立以及二叉树的三种遍历方式“(前序遍历 ...

  3. ZT 二叉树的非递归遍历

    ZT 二叉树的非递归遍历 二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就 是递归定 ...

  4. 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java

    前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...

  5. c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

    二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...

  6. c/c++叉树的创建与遍历(非递归遍历左右中,不破坏树结构)

    二叉树的创建与遍历(非递归遍历左右中,不破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...

  7. 非递归遍历N-ary树Java实现

    2019-03-25 14:10:51 非递归遍历二叉树的Java版本实现之前已经进行了总结,这次做的是非递归遍历多叉树的Java版本实现. 在非递归遍历二叉树的问题中我个人比较推荐的是使用双whil ...

  8. JAVA递归、非递归遍历二叉树(转)

    原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ...

  9. 非递归遍历二叉树Java实现

    2018-10-03 20:16:53 非递归遍历二叉树是使用堆栈来进行保存,个人推荐使用双while结构,完全按照遍历顺序来进行堆栈的操作,当然在前序和后序的遍历过程中还有其他的压栈流程. 一.Bi ...

随机推荐

  1. iOS开发-数据持久化

    iOS中四种最常用的将数据持久存储在iOS文件系统的机制 前三种机制的相同点都是需要找到沙盒里面的Documents的目录路径,附加自己相应的文件名字符串来生成需要的完整路径,再往里面创建.读取.写入 ...

  2. Parallax Occlusion Mapping

    如上图,本来是采样original texture coordinates点的颜色,其实却采样了correcter texture coordinates点的颜色. 而且会随着视线的不同看到凹凸程度变 ...

  3. delphi TTreeView组件遍历磁盘目录

    TTreeView组件遍历磁盘目录 实例说明 TTreeView组件是一个以分枝结构或者说树状结构显示数据的组件,以该组件显示数据具有较好的等级关系和逻辑层次,并且易于操作.在组件中显示的数据结构与系 ...

  4. TOJ 4325 RMQ with Shifts / 线段树单点更新

    RMQ with Shifts 时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte 描述 In the traditional RMQ (Range M ...

  5. iOS开发——动画篇Swift篇&常用动画总结

    UIView动画: UIView动画时最基本的动画,是直接对我们界面上控件进行简单的动画效果实现,如果你只需要用到一些简单的效果,那么这个很适合你,关于UIView动画实现恨简单, UIKit直接将动 ...

  6. SAP SOAMANAGER 配置WEBSERVICE 提示:Service cannot be reached解决方法

    TM中有些服务没有被激活,以UI界面个性化设置化设置为例: 如果服务没有被激活,打开界面就会显示: 这时候右键点击属性,获取服务ID: 通过事务代码SICF,输入服务ID:wd_analyze_con ...

  7. OSGi 学习(一)

    从基础开始,先来说说OSGi的基本理念. OSGi通过隔离底层classloader,强制应用在设计的时候就考虑模块化,并且基于白板模式来支持服务的注册与订阅. 在OSGi中,模块可以等价理解为bun ...

  8. 详解SQL Server连接(内连接、外连接、交叉连接)

    在查询多个表时,我们经常会用“连接查询”.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据 ...

  9. Hive官方手册翻译(Getting Started)(转)

    原文:http://slaytanic.blog.51cto.com/2057708/939950 翻译Hive官方文档系列,文中括号中包含 注: 字样的,为我自行标注的,水平有限,翻译不是完美无缺的 ...

  10. js学习笔记第二篇

    Js笔记整理 1.StringAPI a)        大小写转换:str.toUpperCase();str.toLowerCase(); b)        获取指定位置字符: Str[i]-- ...