欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个通过深度优先方式遍历文件夹(包括子文件夹)的小算法

程序员文章站 2024-03-17 12:08:46
...
#include <windows.h>
#include <tchar.h>
#include <stack>

using namespace std;

//定义回调函数
typedef VOID(* FPTENUMCALLBACK)(LPCTSTR szFullPath, VOID *ptUser);

BOOL EnumDirectory(LPCTSTR szDirectoryPath, FPTENUMCALLBACK EnumCallBack, VOID *ptUser)
{
	if (NULL == szDirectoryPath || NULL == EnumCallBack)
	{
		return FALSE;
	}

	LPTSTR szBaseDirectory = new TCHAR[MAX_PATH * 2];
	if (NULL == szBaseDirectory)
	{
		return FALSE;
	}

	_tcscpy_s(szBaseDirectory, MAX_PATH * 2, szDirectoryPath);
	if (_T('\\') != szBaseDirectory[_tcslen(szBaseDirectory) - 1])
	{
		_tcscat_s(szBaseDirectory, MAX_PATH * 2, _T("\\"));
	}

	stack<LPTSTR> skTasklist;
	skTasklist.push(szBaseDirectory);

	HANDLE hFind = NULL;
	WIN32_FIND_DATA stFindData;

	//开始操作任务栈
	while (FALSE == skTasklist.empty())
	{
		LPTSTR szTask = skTasklist.top();
		skTasklist.pop();

		if (NULL == szTask)
		{
			continue;
		}

		_tcscat_s(szTask, MAX_PATH * 2, _T("*"));

		hFind = FindFirstFile(szTask, &stFindData);
		if (INVALID_HANDLE_VALUE == hFind)
		{
			delete[] szTask;
			continue;
		}

		do 
		{
			LPCTSTR szFileName = stFindData.cFileName;
			if(0 == _tcscmp(szFileName, _T(".")) || 0 == _tcscmp(szFileName, _T("..")))
			{
				continue;
			}

			LPTSTR szFullFileName = new TCHAR[MAX_PATH * 2];
			memset(szFullFileName, 0, sizeof(TCHAR) * MAX_PATH * 2);

			_tcscpy_s(szFullFileName, MAX_PATH * 2, szTask);
			_tcscpy_s(&(szFullFileName[_tcslen(szFullFileName) - 1]), MAX_PATH * 2, szFileName);

			EnumCallBack(szFullFileName, ptUser);		//调用回调函数

			if (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if (_T('\\') != szFullFileName[_tcslen(szFullFileName) - 1])
				{
					_tcscat_s(szFullFileName, MAX_PATH * 2, _T("\\"));
				}
				skTasklist.push(szFullFileName);
			}
			else
			{
				delete[] szFullFileName;
			}
		} while (FindNextFile(hFind, &stFindData));

		delete[] szTask;
		FindClose(hFind);
	}
	return TRUE;
}

回调函数说明

typedef VOID(* FPTENUMCALLBACK)(LPCTSTR szFullPath, VOID *ptUser);

szFullPath : 文件夹中文件的全路径(包括文件夹的路径),不需要在回调函数中释放
ptUser : 一个用户自定义的指针,用来传递想传递的数据结构

使用方法:

定义一个回调函数:

VOID PrintAllFile(LPCTSTR szFullPath, VOID *ptUser)
{
	if(NULL == szFullPath)
	{
		return;
	}
	//输出所有内容
	cout << szFullPath << endl;		//默认窄字符
}

BOOL bError = EnumDirectory(PrintAllFile, NULL);
if(FALSE == bError)
{
	cout << "遍历失败" << endl;
}
else
{
	cout << "遍历成功" << endl;
}