UNIX/Linux上的目录操作。
几个功能:
- 判断是否是目录
- 创建路径
- 递归清理目录
- 递归处理目录的框架
代码不复杂,前三个就是函数(在同一个类中),最后一个是独立类,完整如下:
#include --------------------//这里需要一些基础标准头文件
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>class CDir{public:static bool IsDir(char const * strPathName){struct stat statBuf;if (stat(strPathName, &statBuf) == -1){cout << "stat error : " << strPathName << endl;return false;}return(statBuf.st_mode & S_IFDIR);}static bool CreateDir(char const * filename){string dirname;char const * p = filename;for (; '\0' != *p; ++p){dirname += *p;if ('/' == *p){//thelog<<dirname<<endi;mkdir(dirname.c_str(), S_IRWXU | S_IRWXG);}}return true;}static int ClearDir(char const * dirname, bool isKeepDir, long & count, long & count_err){struct dirent *drip;DIR *dp;string fullname;string inputdir = dirname;if ((dp = opendir(inputdir.c_str())) == NULL){++count_err;thelog << "Error open dir " << inputdir << " : " << strerror(errno) << ende;return __LINE__;}while ((drip = readdir(dp)) != NULL){if (strcmp(drip->d_name, ".") == 0 || strcmp(drip->d_name, "..") == 0)continue;fullname = inputdir + "/" + drip->d_name;//thelog<<fullname<<endi;if (IsDir(fullname.c_str())){ClearDir(fullname.c_str(), isKeepDir, count, count_err);}if (!isKeepDir || !IsDir(fullname.c_str())){if (0 == unlink(fullname.c_str()))++count;else ++count_err;}if (count + count_err > 0 && 0 == (count + count_err) % 10000){cout << "已处理 " << count + count_err << " 删除 " << count << " 个,出错 " << count_err << " 个" << endl;}}closedir(dp);return 0;}};class CForEachDir{private://默认动作的数据int model;//内置的动作,0为显示名称long more_skip;//只处理这么多long doOneFile_count;//doOneFile用的计数private://接口//进入目录时调用一次virtual int doDirBegin(char const * dirname, long deep) { return 0; }virtual int doDirEnd(char const * dirname, long deep) { return 0; }//对每个文件调用一次virtual int doOneFile(char const * filename, bool isDir, long deep){if (0 == model){if (doOneFile_count < more_skip)cout << filename << endl;++doOneFile_count;}else{cout << "未知的模式 " << model << endl;}return 0;}private://内部函数int _doForEachDir(char const * dirname, bool isNoDir, bool r, long & count, long & count_err, long & _, long deep){struct dirent *drip;DIR *dp;string fullname;string inputdir = dirname;if ((dp = opendir(inputdir.c_str())) == NULL){++count_err;DEBUG_LOG << "Error open dir " << inputdir << " : " << strerror(errno) << ende;return __LINE__;}doDirBegin(inputdir.c_str(), deep);while ((drip = readdir(dp)) != NULL){if (strcmp(drip->d_name, ".") == 0 || strcmp(drip->d_name, "..") == 0)continue;fullname = inputdir + "/" + drip->d_name;//thelog<<fullname<<endi;bool isdir = CDir::IsDir(fullname.c_str());if (isdir && r){_doForEachDir(fullname.c_str(), isNoDir, r, count, count_err, _, deep + 1);}if (!isNoDir || !isdir){if (0 == doOneFile(fullname.c_str(), isdir, deep))++count;else ++count_err;}if (_ != count + count_err){_ = count + count_err;if (count + count_err > 0 && 0 == (count + count_err) % 10000){cout << "已处理 " << count + count_err << " 成功 " << count << " 个,出错 " << count_err << " 个" << endl;}}}doDirEnd(inputdir.c_str(), deep);closedir(dp);return 0;}public:CForEachDir():model(-1){}int doForEachDir(char const * dirname, bool isNoDir, bool r, long & count, long & count_err){count = 0;count_err = 0;long tmp = 0;return _doForEachDir(dirname, isNoDir, r, count, count_err, tmp, 0);}int showAllFileName(char const * dirname, long _more_skip = -1){long count;long count_err;model = 0;more_skip = _more_skip;doOneFile_count = 0;return doForEachDir(dirname, true, true, count, count_err);}};
其中“thelog DEBUG_LOG endi”用来输出日志,替换为“cout endl”即可。
有问题问我。
(这里是结束)