转载请注明来源: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. Codeforces Gym 100650D Queens, Knights and Pawns 暴力

    Problem D: Queens, Knights and PawnsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu ...

  2. 读《C# 和 Java 的比较》有感

    网上的一篇<C# 和 Java 的比较>(或者叫<Java 和 C# 的比较>)写的挺不错的,今天忽然搜索到. 自己刚刚接触C#,也不由自主地随时都拿来和Java做对比,所以就 ...

  3. 解决使用DevExpress开发错误:未将对象引用设置到对象的实例

    在使用DevExpress是总是会出现一些状况.这次同事在他的机器上调试完成的代码发过来,却出现"未将对象引用设置到对象的实例"的错误,提示是Resources.resx的问题.另 ...

  4. js中substr与substring的差别

    Js的substring和C#的Substring的作用都是从一个字符串中截取出一个子字符串,但它们的用法却有非常大的不同,下边我们来比較看看:  Js的substring  语法:  程序代码  S ...

  5. Windows 7旗舰版搭建andriod 4.0开发环境记录

    搭建Android环境步骤(仅供参考): 官方搭建步骤: http://developer.android.com/index.html 搭建环境之前需要下载下面几个文件包: 一.安装Java运行环境 ...

  6. centos安装zendstudio centos系统

    查看centos系统32或64位命令(位数):在终端中执行“getconf LONG_BIT”命令并回车键确定 安装zend studio : 1. 首先安装好Java环境yum -y install ...

  7. OpenVPN中的几个和连接相关的Timer解析

    在OpenVPN中存在几个计时器,这些计时器限制着OpenVPN的一些特定行为的最长持续时间,如果设置不好,就会带来莫名其妙的断线问题,然而如何设置这些计数器也没有一个通用的方案,特定情况下不能太大也 ...

  8. TortoiseGit安装教程

    TortoiseGit 是Windows下的可视化Git界面. 下载Git 网站地址: http://code.google.com/p/tortoisegit/ 安装前必须装上msysgit才能在W ...

  9. vim替换命令

    转载:http://blog.csdn.net/glorin/article/details/6317098 替換(substitute) :[range]s/pattern/string/[c,e, ...

  10. 小白日记23:kali渗透测试之提权(三)--WCE、fgdump、mimikatz

    WCE windows身份认证过程 http://wenku.baidu.com/view/cf2ee127a5e9856a56126017.html #特例在登陆的目标服务器/系统,有一个w摘要安全 ...