#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef std::vector<: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 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;
}