非递归遍历所有文件及目录:FindFirstFile,FindNextFile和FindClose

都说用这三个API遍历文件效率比较高,我查了些资料,把它们封装成一个类。

#ifndef _WIN_FILEFINDENUM_H_
#define _WIN_FILEFINDENUM_H_
#include <iostream>
#include <windows.h>
#include <string>
#include <vector>
#include <queue>

class Win_FileFindEnum
{
public:
    Win_FileFindEnum(string);
    void DoErgodicFile(string);
    ~Win_FileFindEnum(){};
private:
    Win_FileFindEnum();
private:
    string rootPath;
    vector<string> FilePath;
    //vector<string> FileName;
};
Win_FileFindEnum::Win_FileFindEnum(string path):rootPath(path)
{
    DoErgodicFile(rootPath);
}
void Win_FileFindEnum::DoErgodicFile(string path)
{
    WIN32_FIND_DATAA fd;
    queue<string> AllDirectory;
    if (path[path.size() - 1] != '\\')
    {
        path = path + "\\";
    }
    AllDirectory.push(path);
    try
    {
        while(!AllDirectory.empty())
        {
            string EveryPath = AllDirectory.front();
            string tempPath = EveryPath + "*";

            HANDLE hFind = ::FindFirstFileA(tempPath.c_str(), &fd);
            if (hFind == INVALID_HANDLE_VALUE)
            {
                ::FindClose(hFind);
                return;
            }
            do
            {
                string isFile = fd.cFileName;
                if((fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0)
                {
                    //cout<<"path"<<EveryPath<<isFile<<endl;
                    FilePath.push_back(EveryPath + isFile);
                }
                else if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && (isFile != "." && isFile != ".."))
                {
                    string Rp = EveryPath + fd.cFileName + "\\";
                    AllDirectory.push(Rp);
                }
            }while(::FindNextFileA(hFind, &fd));
            AllDirectory.pop();
            ::FindClose(hFind);
        }
    }catch(...){ return;}
}
#endif//_WIN_FILEFINDENUM_H_
 
以下内容为引用别人的博客------WIN32_FIND_DATA结构详解
WIN32_FIND_DATA结构描述了一个由FindFirstFile, FindFirstFileEx, 或FindNextFile函数查找到的文件信息, 

typedef struct _WIN32_FIND_DATA {

   DWORD dwFileAttributes; //文件属性

   FILETIME ftCreationTime; // 文件创建时间

   FILETIME ftLastAccessTime; // 文件最后一次访问时间

   FILETIME ftLastWriteTime; // 文件最后一次修改时间

   DWORD nFileSizeHigh; // 文件长度高32位

   DWORD nFileSizeLow; // 文件长度低32位

   DWORD dwReserved0; // 系统保留

   DWORD dwReserved1; // 系统保留

   TCHAR cFileName[ MAX_PATH ]; // 长文件名

   TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名

} WIN32_FIND_DATA, *PWIN32_FIND_DATA;

可以通过FindFirstFile()函数根据当前的文件存放路径查找该文件来把待操作文件的相关属性读取到WIN32_FIND_DATA结构中去:

WIN32_FIND_DATA ffd ;

HANDLE hFind = FindFirstFile("c:\\test.dat",&ffd);

在使用这个结构时不能手工修改这个结构中的任何数据,结构对于开发人员来说只能作为一个只读数据,其所有的成员变量都会由系统完成填写。在MSDN帮助中可以查找到关于WIN32_FIND_DATA结构的更加详细的说明。

if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

这个判断语句是通过 将dwFileAttributes和FILE_ATTRIBUTE_DIRECTORY做位的与运算
来判断所找到的项目是不是文件夹

因为 FindFirstFile返回的 findData 中 dwFileAttributes项的值

可能是
FILE_ATTRIBUTE_ARCHIVE
FILE_ATTRIBUTE_COMPRESSED
FILE_ATTRIBUTE_DIRECTORY
FILE_ATTRIBUTE_HIDDEN
FILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_OFFLINE
FILE_ATTRIBUTE_READONLY
FILE_ATTRIBUTE_SYSTEM
FILE_ATTRIBUTE_TEMPORARY
中几项的组合值

findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
的结果只能是两种:
FILE_ATTRIBUTE_DIRECTORY 非零值 ,if条件是真
0 ,if条件是假

通过 findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
可以判断 dwFileAttributes项的值中是否 FILE_ATTRIBUTE_DIRECTORY,即判断所找到的项目是不是文件夹

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chenyongsuda/archive/2010/08/04/5788268.aspx

转载于:https://www.cnblogs.com/cluster/archive/2011/06/30/2095123.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言在Windows下遍历目录文件的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> void traverse_dir(const char *path); int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <dir_path>\n", argv[0]); return 1; } traverse_dir(argv[1]); return 0; } void traverse_dir(const char *path) { char search_path[MAX_PATH]; WIN32_FIND_DATA file_data; sprintf(search_path, "%s\\*", path); HANDLE handle = FindFirstFile(search_path, &file_data); if (handle == INVALID_HANDLE_VALUE) { printf("Failed to open directory: %s\n", path); return; } do { if (strcmp(file_data.cFileName, ".") == 0 || strcmp(file_data.cFileName, "..") == 0) { continue; } if (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // 子目录 char sub_path[MAX_PATH]; sprintf(sub_path, "%s\\%s", path, file_data.cFileName); traverse_dir(sub_path); } else { // 文件 char file_path[MAX_PATH]; sprintf(file_path, "%s\\%s", path, file_data.cFileName); printf("%s\n", file_path); } } while (FindNextFile(handle, &file_data)); FindClose(handle); } ``` 在此代码中,我们使用了Windows API中的`FindFirstFile`和`FindNextFile`函数来遍历目录文件。具体实现步骤如下: 1. 将指定目录的路径拼接成搜索路径,例如`C:\test\*`。 2. 调用`FindFirstFile`函数来打开目录并获取第一个文件目录的信息。 3. 如果打开目录失败,则退出遍历函数。 4. 如果当前文件目录是`.`或`..`,则跳过。 5. 如果当前文件目录目录,则递归调用遍历函数。 6. 如果当前文件目录文件,则打印文件路径。 7. 调用`FindNextFile`函数获取下一个文件目录的信息,重复步骤4-6,直到遍历完整个目录。 8. 调用`FindClose`函数关闭目录句柄。 需要注意的是,我们在拼接子目录路径和文件路径时,使用了`sprintf`函数。为了避免缓冲区溢出,我们将缓冲区大小定义为`MAX_PATH`,这是一个Windows API中的常量,表示文件路径的最大长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值