linux c++带通配找文件 枚举文件 目录

来源:互联网 发布:windows程序开发c#版 编辑:程序博客网 时间:2024/06/03 08:25
#include <stdio.h>#include <string.h>#include <sys/types.h>#include <dirent.h>#include <sys/stat.h>#include <vector>#include <string>#include <stack>using namespace std;typedef std::vector<std::string> filePathArr;enum EnumFileType{  EnumFileType_File,  EnumFileType_Directory};#define MATCH_CHAR(c1,c2,ignore_case)  ( (c1==c2) || ((ignore_case) &&(tolower(c1)==tolower(c2))) )//EnumWildCharMatch通配匹配函数来自于:http://blog.csdn.net/c80486/article/details/6584769//感谢作者让我方便不少,谢谢bool EnumWildCharMatch(const char *src, const char *pattern, bool ignore_case){bool result = false;while (*src){if (*pattern == '*'){  /* 如果 pattern 的当前字符是 '*' *//* 如果后续有多个 '*', 跳过 */while ((*pattern == '*') || (*pattern == '?'))pattern++;/* 如果 '*" 后没有字符了,则正确匹配 */if (!*pattern) return true;/* 在 src 中查找一个与 pattern中'*"后的一个字符相同的字符*/while (*src && (!MATCH_CHAR(*src,*pattern,ignore_case)))src++;/* 如果找不到,则匹配失败 */if (!*src) return false;/* 如果找到了,匹配剩下的字符串*/result = EnumWildCharMatch (src, pattern, ignore_case);/* 如果剩下的字符串匹配不上,但src后一个字符等于pattern中'*"后的一个字符 *//* src前进一位,继续匹配 */while ( (!result) && (*(src+1)) && MATCH_CHAR(*(src+1),*pattern,ignore_case) )result = EnumWildCharMatch (++src, pattern, ignore_case);return result;}else{/* 如果pattern中当前字符不是 '*' *//* 匹配当前字符*/if ( MATCH_CHAR(*src,*pattern,ignore_case) || ('?' == *pattern))  /* src,pattern分别前进一位,继续匹配 */  return EnumWildCharMatch (++src, ++pattern, ignore_case);else   return false;}}/* 如果src结束了,看pattern有否结束*//* pattern没有结束*//* 如果pattern有最后一位字符且是'*' */if (*pattern)return (*pattern == '*') && (*(pattern+1) == 0);return true;}//枚举文件/目录,返回找到的文件个数//鉴于最近才开始在linux下工作,就一个寻找文件函数费了我2个小时时间,但愿后来者能节省这2个小时,多干些别的事情.//Hope. size_t EnumFiles( const char* path,//需要枚举的路径 filePathArr& out,//枚举结果输出存储 const char* filter = "*",//通配符过滤器,支持*跟?匹配,比如“*.jpg", "?.jpg" bool inc_sub_dirs = true,//是否包含子目录,枚举的时候需要把子目录也给翻一遍吗? bool clear_out = true,//执行前是否清空out中的数据 EnumFileType type = EnumFileType_File,//指定需要查找的文件类型,是目录呢,还是文件 unsigned int nFilePerDir = 0//指定每个文件夹中只搜寻指定个文件/目录即可){  char real_path[260];  size_t length = strlen(path);  if(clear_out)  out.clear();  strcpy(real_path, path);  if (real_path[length - 1] != '/')  strcat(real_path, "/");  stack<string> ps;  size_t nOldCount = out.size();  ps.push(real_path);  while(!ps.empty())  {  unsigned int nAlreadyCount = 0;  string search_path = ps.top();  ps.pop();  DIR* dir = opendir((search_path).c_str());  if(dir != 0)  {  struct stat file_stat;  struct dirent *s_dir = readdir(dir);  do  {  if ((strcmp(s_dir->d_name,".")==0)||(strcmp(s_dir->d_name,"..")==0)) continue;  stat((search_path + s_dir->d_name).c_str(),&file_stat);  bool curIsDir = S_ISDIR(file_stat.st_mode);  if ((type == EnumFileType_File && !curIsDir) ||  (type == EnumFileType_Directory && curIsDir))  {  if (EnumWildCharMatch(s_dir->d_name, filter, false))  out.push_back(search_path + s_dir->d_name);  if (inc_sub_dirs)  ps.push(search_path + s_dir->d_name + "/");  if(nFilePerDir > 0 && ++nAlreadyCount == nFilePerDir) break;  }  else  {  if (inc_sub_dirs && curIsDir)  ps.push(search_path + s_dir->d_name + "/");  }  }while((s_dir = readdir(dir)) != 0);  closedir(dir);  }  }  return out.size() - nOldCount; }int main(){filePathArr fs;EnumFiles("/usr/lib", fs, "*.so", false, true);for(size_t i = 0; i < fs.size(); ++i)printf("fs[ %d ]: %s\n", i, fs[i].c_str());return 0;}

0 0