You can use it in any way, but the author name should always be there. It's nice to leave your suggestions. //author: huanghaifeng #include <stddef.h> #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <stdlib.h> #include <string.h> #include <vector> #include <string> class CDir { public: enum ENUMTYPE{ISFILE, ISDIR}; typedef bool (*HANDLE_FILE)(std::string&); typedef void (*HANDLE_ERROR)(std::string&, ENUMTYPE); explicit CDir(char* path); ~CDir(); void setCallBack(HANDLE_FILE fun); void setErrorHandler(HANDLE_ERROR fun); void setPath(char* path); //only traverse current level bool TraverseMyself(); //traverse all files in any directory level, //with each of them as a parameter call the callback function void TraverseAllFilesAndCallBack(HANDLE_FILE fun, HANDLE_ERROR errFun); private: HANDLE_FILE pFun; HANDLE_ERROR pErr; std::string path_; std::vector<std::string> files_; std::vector<std::string> dirs_; CDir(const CDir&); CDir& operator=(const CDir&); }; CDir::CDir(char* path):path_(path),pFun(NULL),pErr(NULL) { } CDir::~CDir() { } bool CDir::TraverseMyself() { files_.clear(); dirs_.clear(); DIR* dp; struct dirent* ep; const char* tmpPath=path_.c_str(); char absolutePath[PATH_MAX]={0}; if(NULL == realpath(tmpPath,absolutePath)) { return false; } path_=absolutePath; dp=opendir(absolutePath); if(dp!=NULL) { while(ep=readdir(dp)) { if(strcmp(ep->d_name,".")!=0 && strcmp(ep->d_name,"..")!=0) { switch(ep->d_type) { case DT_REG: files_.push_back(std::string(absolutePath).append("/").append(ep->d_name)); break; case DT_DIR: dirs_.push_back(std::string(absolutePath).append("/").append(ep->d_name)); break; default: break; } } } closedir(dp); } else { return false; } return true; } void CDir::setCallBack(HANDLE_FILE fun) { pFun = fun; } void CDir::setErrorHandler(HANDLE_ERROR fun) { pErr = fun; } void CDir::setPath(char* path) { path_ = path; } void CDir::TraverseAllFilesAndCallBack(HANDLE_FILE fun, HANDLE_ERROR errFun) { //callback function not exist if(fun == NULL)return; pFun = fun; pErr = errFun; //traverse to find out files and directories in current dir-level if(TraverseMyself() == false) { if(pErr != NULL)pErr(path_, ISDIR); return; } //do the job for each file in current dir-level std::vector<std::string>::iterator ite = files_.begin(); for( ; ite!=files_.end() ; ++ite) { if(pFun(*ite) == false) { if(pErr != NULL)pErr(*ite, ISFILE); } } //find out other sub-direcotries and call the recursive function std::vector<std::string>::iterator dite = dirs_.begin(); for( ; dite!=dirs_.end() ; ++dite) { CDir sdir(const_cast<char*>((*dite).c_str())); sdir.TraverseAllFilesAndCallBack(pFun, pErr); } } bool PrintFile(std::string& filename) { printf("%s/n", filename.c_str()); return true; } void ErrorHandler(std::string& name, CDir::ENUMTYPE type) { if(type == CDir::ISFILE)printf("error file:%s/n", name.c_str()); if(type == CDir::ISDIR)printf("error dir:%s/n", name.c_str()); } int main(void) { CDir dir("./testdir"); dir.TraverseAllFilesAndCallBack(PrintFile, ErrorHandler); return 0; }