遍历(广度优先)windows系统某一目录
来源:互联网 发布:mybatis 打印完整sql 编辑:程序博客网 时间:2024/05/18 15:24
遍历目录的类(广度优先),本来想找一段代码了事,后来没发现合适的,自己写了一个,分享给大家。其中用到一个线程类,也是自己封装的,与主题无关不贴出来,有需要的话去我的资源里找吧。
directory_traversal.h文件
#ifndef DIRECTORY_TRAVERSAL_H__#define DIRECTORY_TRAVERSAL_H__#include <windows.h>#include <queue>#include "hthread.h"struct FileInfo{ FileInfo(); FileInfo(const FileInfo&); FileInfo& operator=(const FileInfo&); WIN32_FIND_DATAW file_data; wchar_t path[MAX_PATH]; size_t level;};int MakePath(wchar_t* file_path, size_t size, const wchar_t* parent_path, const wchar_t* file_name);FileInfo MakeFileInfo(const wchar_t* parent_path, size_t level, const WIN32_FIND_DATA& cur_fd);class DirectoryTraversal{public: typedef bool (*callback_find)(const FileInfo* , void*); typedef void (*callback_complete)(bool , void*); DirectoryTraversal(); virtual ~DirectoryTraversal(); // 设置遍历参数 void SetCallback(callback_find cb_find, void* p1, callback_complete cb_complete, void* p2); // 启动遍历线程 int Start(const wchar_t* begin_path, size_t max_level); int BreadthFirstTravers(const wchar_t* begin_path, size_t max_level); void SetStopFlag();private: static unsigned int __stdcall ThreadTravers(void* lp); // 用递归方法,遍历d:\\w导致栈溢出 //int BreadthFirstTravers(const wchar_t* path, size_t level); /* 如果cb_find返回bool型, 一般应返回true, 如果返回false且当前文件是目录, 则不遍历此目录下的文件 p作为cb_find的参数. */ HANDLE FindFirstSubFile(const wchar_t* path, WIN32_FIND_DATA* fd);protected: wchar_t begin_path_[MAX_PATH]; size_t max_level_; // 遍历级数 bool stop_; callback_find cb_find_; void* find_para_; callback_complete cb_complete_; void* complete_para_; HThread thread_; std::queue<FileInfo> folder_queue_;};#endif
#include <Shlwapi.h>#include <string.h>#include <assert.h>#include <wchar.h>#include "directory_traversal.h"#pragma comment(lib,"shlwapi.lib")FileInfo::FileInfo(){ level = 0; memset(path, 0, sizeof(path));}FileInfo::FileInfo(const FileInfo& r){ this->file_data = r.file_data; wcscpy_s(this->path, MAX_PATH, r.path); this->level = r.level;}FileInfo& FileInfo::operator=(const FileInfo& r){ if(&r != this) { this->file_data = r.file_data; wcscpy_s(this->path, MAX_PATH, r.path); this->level = r.level; } return *this;}int MakePath(wchar_t* file_path, size_t size, const wchar_t* parent_path, const wchar_t* file_name){ int ret = wcscpy_s(file_path, size, parent_path); if (0 == ret) ret = PathAppendW(file_path, file_name) ? 0 : -1; return ret;}FileInfo MakeFileInfo(const wchar_t* parent_path, size_t level, const WIN32_FIND_DATAW& cur_fd){ FileInfo cur_folder; MakePath(cur_folder.path, MAX_PATH, parent_path, cur_fd.cFileName); cur_folder.file_data = cur_fd; cur_folder.level = level; return cur_folder;}DirectoryTraversal::DirectoryTraversal() : stop_(false){}DirectoryTraversal::~DirectoryTraversal(){ thread_.WaitExit();}void DirectoryTraversal::SetCallback(callback_find cb_find, void* p1, callback_complete cb_complete, void* p2){ cb_find_ = cb_find; find_para_ = p1; cb_complete_ = cb_complete; complete_para_ = p2;}int DirectoryTraversal::Start(const wchar_t* begin_path, size_t max_level){ stop_ = false; wcscpy_s(begin_path_, MAX_PATH, begin_path); // 线程启动前要保存传入的数据 max_level_ = max_level; thread_.Start(&DirectoryTraversal::ThreadTravers, this); return 0;}unsigned int __stdcall DirectoryTraversal::ThreadTravers(void* lp){ DirectoryTraversal* self = (DirectoryTraversal*)lp; if(wcslen(self->begin_path_) == 0) return -1; return self->BreadthFirstTravers(self->begin_path_, self->max_level_);}int DirectoryTraversal::BreadthFirstTravers(const wchar_t* begin_path, size_t max_level){ while(!folder_queue_.empty()) folder_queue_.pop(); HANDLE find_file = INVALID_HANDLE_VALUE; WIN32_FIND_DATAW fd; wchar_t cur_path[MAX_PATH]; wcscpy_s(cur_path, MAX_PATH, begin_path); size_t cur_level = 1; do { if (max_level > 0 && cur_level > max_level) { if (cb_complete_) (*cb_complete_)(stop_, complete_para_); return 0; } find_file = FindFirstSubFile(cur_path, &fd); if (INVALID_HANDLE_VALUE == find_file) { assert(false); if (cb_complete_) (*cb_complete_)(stop_, complete_para_); return -1; } FileInfo new_find_file; do { if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { new_find_file = MakeFileInfo(cur_path, cur_level, fd); if(cb_find_) (*cb_find_)(&new_find_file, find_para_); } else { if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) && 0 != wcscmp(fd.cFileName, L".") && 0 != wcscmp(fd.cFileName, L"..")) { new_find_file = MakeFileInfo(cur_path, cur_level, fd); if(cb_find_){ if((*cb_find_)(&new_find_file, find_para_)) folder_queue_.push(new_find_file); } else folder_queue_.push(new_find_file); } } if (stop_) break; } while(FindNextFileW(find_file, &fd)); FindClose(find_file); if(stop_ || folder_queue_.empty()) { if (cb_complete_) (*cb_complete_)(stop_, complete_para_); return 0; } FileInfo next_folder = folder_queue_.front(); folder_queue_.pop(); cur_level = next_folder.level + 1; wcscpy_s(cur_path, MAX_PATH, next_folder.path); } while(true);}void DirectoryTraversal::SetStopFlag(){ stop_ = true;} HANDLE DirectoryTraversal::FindFirstSubFile(const wchar_t* path, WIN32_FIND_DATAW* fd) { wchar_t buffer[MAX_PATH]; wcscpy_s(buffer, MAX_PATH, path); if(!PathAppendW(buffer, L"*.*")) return NULL; return FindFirstFileW(buffer, fd); }
- 遍历(广度优先)windows系统某一目录
- 广度优先遍历目录(Windows平台、C++)
- windows下广度和深度目录遍历
- linux(c)广度优先遍历指定目录
- 广度优先遍历BFS
- 广度优先遍历
- 图--广度优先遍历
- 图广度优先遍历
- 广度优先遍历
- 广度优先遍历-示例
- 广度优先遍历代码
- 广度优先遍历
- 广度优先遍历
- 广度优先遍历
- Leetcode - 广度优先遍历
- 广度优先遍历
- BFS广度优先遍历
- 广度优先遍历
- View和其subview的半透明问题
- centos 6.2 编译cowpatty-4.6遇到的问题
- ISF 视频下载地址(持续更新)
- 滚动到页顶
- ECMALL get_options 生成下拉菜单
- 遍历(广度优先)windows系统某一目录
- 将Excel导入到虚拟DataTable中
- 归并排序求逆序数java
- 关于adb server didn't ack failed to start daemon
- android性能优化之context的优化
- 从PL/SQL中导出insert语句
- linux 下三种方式获取本机IP地址
- 购物车--产品图片飞入购物车
- Web缓存技术概述