一、win32下文件的递归遍历【深度遍历】
递归遍历Demo如下:
void FileSearch(char* searchDir)
{
char dirInfo[BUF];
WIN32_FIND_DATA fd;
strcpy(dirInfo,searchDir);
strcat(dirInfo,"\\*.*");//查询文件地址
strcpy(dirInfo+strlen(dirInfo),"\0");
HANDLE hFind = ::FindFirstFile(dirInfo, &fd);//第一个文件句柄
if(hFind == INVALID_HANDLE_VALUE)
return;
else
{
while(FindNextFile(hFind, &fd))
{
puts(fd.cFileName);
//过滤当前文件,并区分文件和目录
if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp(fd.cFileName ,"..")!=0)
{
//构造下一次递归的地址
strcpy(dirInfo,searchDir);
strcat(dirInfo,"\\");
strcat(dirInfo,fd.cFileName);
FileSearch(dirInfo);
}
}
FindClose(hFind);
return;
}
}
这种方法遍历文件的优点:思路简单。缺点:由于需要多次压栈,导致程序不稳定。
二、非递归遍历【层次遍历】
思路:windows查找也是根据文件树的层次进行查找的,这种查找的优点是,可以分层进行,不需要占用过多的内存空间。有两种方法可以实现层次遍历:
1、用队列。逐层入队,然后出队,若是文件则输出文件信息,若是目录,则入队。再从队中取出下一个元素,以此类推。当队列为空,文件遍历结束。
2、双链表。定义两个链表,如目录链表path_list和文件链表filename_list。用目录链表path_list存读取出来的目录,用文件链表filename_list存相应目录下的文件。分层遍历文件,将每一层的目录和文件分别存入目录链表和文件链表中。依次循环从目录文件中取目录进行遍历。
下面是第二种思路的实现:
list <string> path_name;
list <string> path;
void order()
{
WIN32_FIND_DATA fd;
string temp,tempEx, tempDir;
/*当path不空时,继续执行相同动作*/
path.push_back("D:\\test");
while(!path.empty())
{
tempEx = temp = path.back();
tempEx.append("\\*.*");
HANDLE hFind = ::FindFirstFile(tempEx.c_str(), &fd);
puts(tempEx.c_str());
if(hFind == INVALID_HANDLE_VALUE)
{
puts("NO FILE FOUND!!");
//return ;
}
/*删除已使用过的目录*/
path.pop_back();
/*输出单层文件夹中的文件,目录输入path,文件输入path_name*/
while(::FindNextFile(hFind, &fd))
{
/*判断是否是目录,若是目录则if,或者else
将地址一起写入??*/
if((FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY)
{
if(strcmp(fd.cFileName ,"..")!=0)
{
/*构造路径,tempDir可以保证路径暂时不变*/
tempDir = temp;
tempDir.append("\\");
tempDir.append(fd.cFileName);
path.push_front(tempDir);
}
}
else
path_name.push_front(fd.cFileName);
}
FindClose(hFind);
}
/*输出文件*/
for_each(path_name.begin(), path_name.end(), Print);
return;
}
int Print (string& StringToPrint)
{
cout << StringToPrint << endl;
return 1;
}