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

要点:

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

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

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

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

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

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

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

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

流程图如下:

需要引入的头文件:

#include <stack>
#include <iostream>
#include <fstream>
#include <list>
#include <set>

  

回调函数定义:

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

  

实现代码如下:

STDMETHODIMP CFileTool::SearchFiles(BSTR topDirectoryName, BSTR key, HWND mainWnd,long callbackAddress)
{
HINSTANCE dllInst=(HINSTANCE)GetModuleHandle(L"xssfj.dll"); WCHAR finishedMsg[256]={0};
LoadString(dllInst,IDS_FILE_DELETESPECIFY_SEARCHSUCCESS,finishedMsg,256);
XCallbackMethodType callbackMsg=(XCallbackMethodType)callbackAddress;
DWORD attribute=GetFileAttributesW(topDirectoryName);
if(!(attribute&FILE_ATTRIBUTE_DIRECTORY))
return E_INVALIDARG;
if(!callbackMsg)
return E_INVALIDARG;
if(StrStrI(topDirectoryName,key))
{
callbackMsg(mainWnd,topDirectoryName,2);
callbackMsg(mainWnd,finishedMsg,0);
return S_OK;
}
std::stack<WCHAR*> directoryNameStack;
WCHAR* tmpStackData=(WCHAR*)calloc(MAX_PATH,sizeof(WCHAR));
lstrcpyW(tmpStackData,topDirectoryName);
directoryNameStack.push(tmpStackData);
while(!directoryNameStack.empty())
{
WCHAR* currentDirName=directoryNameStack.top();
directoryNameStack.pop();
callbackMsg(mainWnd,currentDirName,1);
WCHAR tmpParentPath[MAX_PATH]={0};
lstrcpy(tmpParentPath,currentDirName);
if(currentDirName[lstrlen(currentDirName)-1]!='\\')
{
lstrcat(tmpParentPath,L"\\");
lstrcat(currentDirName,L"\\*.*");
}
else
lstrcat(currentDirName,L"*.*");
WIN32_FIND_DATA meiju={0}; HANDLE tmpHandle=FindFirstFile(currentDirName,&meiju);
if(tmpHandle!=INVALID_HANDLE_VALUE&&tmpHandle)
{
if(lstrcmpW(meiju.cFileName,L".")!=0&&lstrcmpW(meiju.cFileName,L"..")!=0)
{
if(StrStrI(meiju.cFileName,key))
{
WCHAR tmpFsObj[MAX_PATH]={0};
lstrcpyW(tmpFsObj,tmpParentPath);
lstrcat(tmpFsObj,meiju.cFileName);
callbackMsg(mainWnd,tmpFsObj,2);
}
}
do
{
DWORD tmpFileResult=FindNextFile(tmpHandle,&meiju);
if(tmpFileResult==ERROR_NO_MORE_FILES||tmpFileResult==0)
break;
if(lstrcmpW(meiju.cFileName,L".")==0||lstrcmpW(meiju.cFileName,L"..")==0)
continue;
if(StrStrI(meiju.cFileName,key))
{
WCHAR tmpFsObj[MAX_PATH]={0};
lstrcpyW(tmpFsObj,tmpParentPath);
lstrcat(tmpFsObj,meiju.cFileName);
callbackMsg(mainWnd,tmpFsObj,2);
}
else
{
WCHAR tmpFsobjPath[MAX_PATH]={0};
lstrcpy(tmpFsobjPath,tmpParentPath);
lstrcat(tmpFsobjPath,meiju.cFileName);
callbackMsg(mainWnd,tmpFsobjPath,1);
DWORD tmpFileAttribute=GetFileAttributes(tmpFsobjPath);
if(tmpFileAttribute&FILE_ATTRIBUTE_DIRECTORY)
{
WCHAR* tmpData=(WCHAR*)calloc(MAX_PATH,sizeof(WCHAR));
lstrcpy(tmpData,tmpFsobjPath);
directoryNameStack.push(tmpData);
}
}
}
while(true);
FindClose(tmpHandle);
}
free(currentDirName);
}
callbackMsg(mainWnd,finishedMsg,0);
return S_OK;
}

  

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. 利用微软Speech SDK 5.1开发语音识别系统主要步骤

    利用微软Speech SDK 5.1开发语音识别系统主要步骤 2009-09-17 10:21:09|  分类: 知识点滴|字号 订阅 微软语音识别分两种模式:文本识别模式和命令识别模式.此两种模式的 ...

  2. PostgreSQL的 initdb 源代码分析之十三

    继续分析: /* Bootstrap template1 */ bootstrap_template1(); 展开: 我这里读入的文件是:/home/pgsql/project/share/postg ...

  3. LCD_ILI9320横竖屏方向的问题。

    发现仅仅设置R03H是不能设置方向的,还需要设置R32H,R33H的坐标位置. 比如我现在是 R03H=0x1000H,R20H=239-x,R21H=319-y:竖直正向 R03H=0x1030H, ...

  4. poj1190生日蛋糕

    生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12277 Accepted: 4325 Description 7月1 ...

  5. delphi 05 图片和超链接

    超链接 /取消超链接 插入/取消 书签 插入图片 粘贴图上CTRL+v 截图 插入表情GIF WEB背景色 WEB背景图片      WebBrowser1.OleObject.document.ge ...

  6. Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)

    一.通过Intent消息机制发送消息,调用系统应用进行,实现apk的安装/卸载 . (1) 调用系统的安装应用,让系统自动进行apk的安装 String fileName = "/data/ ...

  7. strassen algorithm

    the explaination that is clear in my view is from wiki.

  8. truncate 与 delete 的区别

    Delete删除的数据可以通过日志文件进行恢复 Truncate Table删除的数据不能进行恢复 Delete删除时,标识列取值保留原使用中最大值 Truncate Table删除时,标识列恢复到最 ...

  9. C#_自动测试2_连连看外挂

    GUI自动化测试和做外挂的原理很相似,都是模拟用户的鼠标和键盘操作, 给自己的程序写自动化就是做测试,给别人的程序写自动化就是外挂了. 本文使用的技术也同样适用制作“对对碰”,"找茬&quo ...

  10. 详解MySQL中EXPLAIN解释命令

    Explain 结果解读与实践   基于 MySQL 5.0.67 ,存储引擎 MyISAM .   注:单独一行的"%%"及"`"表示分隔内容,就象分开“第一 ...