时间 :
2013-01-30 11:18
摘要:
遍历一个指定文件夹下的所有文件,基于广度优先思想,也可认为是树形结构的层次遍历
编写背景:
在做Adobe Acrobat插件时收到一个需求,Adobe有一个菜单功能是让用户指定一个folder,然后把foler下的所有文件导入到pdf中,用户要求hook这个过程,当用户指定一个folder时,判断folder下是否有敏感文件,如果有则取消本次操作。
个人感觉对于这样的需求,使用广度优先算法,找到敏感文件的时间必少于深度优先。
代码:
bool EnumFiles_Breadth_Fisrt(string RootFolder,bool (*DoWork)(string curFile)) //Level traversal ,
{
// need RootFolder optimization
//optimization RootFolder
if (!iends_with(RootFolder,"\\")) RootFolder+="\\";
DWORD dw=::GetFileAttributesA(RootFolder.c_str() );
if( !(dw&FILE_ATTRIBUTE_DIRECTORY) )return false; // Folder only
// Currently Find *.*
queue<string> runtimeQueue; //each node is path+filetpye
runtimeQueue.push(RootFolder+"*.*");
//Breadth-first
do
{
WIN32_FIND_DATAA fd;
string curSearchPattern(runtimeQueue.front()); // current FindFileTpye
string curfolder=curSearchPattern.substr(0,curSearchPattern.find_last_of('\\')+1);
// cout<<curfolder.c_str()<<endl;
HANDLE hFind = ::FindFirstFileA(curSearchPattern.c_str(),&fd);
if (INVALID_HANDLE_VALUE == hFind ) return false;
do
{
if (fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
if( !iequals(fd.cFileName,".") && !iequals(fd.cFileName,"..") )
{
string internalfolder(curfolder+fd.cFileName+"\\"); //a sub Folder
runtimeQueue.push(internalfolder+"*.*"); //currently find type
}
}
else
{
if(false==(*DoWork)(curfolder+fd.cFileName)) return false;
}
}while(FindNextFileA(hFind,&fd));
runtimeQueue.pop();
FindClose(hFind);
} while (!runtimeQueue.empty());
return true;
}