转载请注明来源: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. 用python查看URL编码的中文

    什么是URL编码呢,请看https://zh.wikipedia.org/wiki/Urlencode. 有时,我们向一些网站提交中文参数时,中文是会被编码成这种格式的 "%B1%E0%C2 ...

  2. linux重启oracle 各种方法

    在linux下重启oracle数据库及监听器总结: 方法1: 用root以ssh登录到linux,打开终端输入以下命令: cd $ORACLE_HOME   #进入到oracle的安装目录 dbsta ...

  3. 记录一下在WinXP上搭建Apache的httpd+PHP+MySQL+Wordpress的过程

    实验室有台旧电脑,想用它一台服务器. 不知为何,U盘启动盘死活不能启动,所以放弃了安装Linux的念头,直接在原来的XP上弄一个服务器,毕竟用的人也不多,也就局域网的这几个人, 本来主要是搭建一个FT ...

  4. JQuery Plugin 2 - Passing Options into Your Plugin

    overriding the default options with user-supplied options and the jQuery extend() method eg: $.fn.pu ...

  5. C# 中的 lock的陷阱

    旧事重提了,或许很多人会奇怪,为什么 C# 不允许lock一个struct ? 例如: public void ProcessTask(int taskid){     lock(taskid){  ...

  6. 解决fedora64下vim不能语法着色问题

    初始状态是vim打开任何文件都没有高亮迹象,接不是彩色,也没有下划线,好了,看怎么一步步解决的... 1)#vim ~/.vimrc 竟然没有这个文件,创建之#touch vim ~/.vimrc 添 ...

  7. 数据库插入某些数据会变成?,或则select无法读出数据库中的某些数据

    如果你想在数据库中插入“uɷ”,这个字符,直接插入 insert into table value (‘uɷ’),是不行的,这样插入的后果是打开数据后会显示为u?.当你面对这个问题的时候是不是第一个想 ...

  8. [Effective C++ --028]避免返回handles指向对象内部成分

    假设程序涉及矩形.每个矩形由其左上角和右下角表示.为了让Rectangle对象尽可能小,可能把定义矩形的点放在一个辅助的struct内再让Rectangle去指它: class Point { // ...

  9. jquery hasClass()、is() 多个

    一..hasClass() hasClass()方法是用来检查被选择的元素是否包含指定的class名,其语法: $(selector).hasClass("className"); ...

  10. Build类

    在开发中 我们有时候会需要获取当前手机的系统版本来进行判断,或者需要获取一些当前手机的硬件信息. android.os.Build类中.包括了这样的一些信息.我们可以直接调用 而不需要添加任何的权限和 ...