Win32非递归遍历和搜索文件以及目录算法

转载请注明来源: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;
}

  

posted @ 2014-08-06 09:34  岬淢箫声  阅读(922)  评论(0编辑  收藏  举报