c++ 遍历查找win指定路径下指定类型的文件

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <io.h>
#include <windows.h>  
#include <string>
#include <vector>
#include <iomanip>

#define MY_NOT_CHECK  1;
#define MY_CHECKED  0;
using namespace std;

int main(){
    string path("c:\\Windows\\system32"), exd("exe");
    vector<WIN32_FIND_DATA> files;
    void getFiles(string path, string exd, vector<WIN32_FIND_DATA>& files);
    
    getFiles(path, exd, files);
   
    sort(files);

    show(files);
}

/*遍历文件夹,得到所有exe文件*/
void getFiles(string path, string exd, vector<WIN32_FIND_DATA>& files)
{
    /************************************************************************/
    /*  获取文件夹下所有文件名
    输入:
    path    :    文件夹路径
    exd        :   所要获取的文件名后缀,如jpg、png等;
    文件名, exd = ""
    输出:
    files    :    获取的文件名列表
    */
    /************************************************************************/
    BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege);

    //文件句柄
    HANDLE  hFile = INVALID_HANDLE_VALUE,hExe = INVALID_HANDLE_VALUE;
    //文件信息
    WIN32_FIND_DATA fileinfo,exeinfo;
    string pathName, exdName = "\\*";
    PVOID OldValue = NULL;
    
    // 关闭系统重定向
    if (Wow64DisableWow64FsRedirection(&OldValue))
    {
        // 查找指定路径
        hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo);

        if (FALSE == Wow64RevertWow64FsRedirection(OldValue))
        {
            return;
        }
    }
    

    // 查找指定路径
    // hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo);

    // 是否查找失败
    if (hFile == INVALID_HANDLE_VALUE)
    {
        // 是否因为权限不足,若不足,则提升权限
        if (GetLastError() == 5)
        {
            HANDLE hToken;
            BOOL bRet = OpenProcessToken(
                GetCurrentProcess(),    // 进程句柄(当前进程)
                TOKEN_ALL_ACCESS,    // 全权访问令牌
                &hToken    // 返回的参数 进程令牌句柄 (就是AdjustTokenPrivileges的第一个参数)
                ); // 获取进程的令牌句柄
            if (bRet != TRUE)
            {
                cout << "获取令牌句柄失败!" << endl;
                return;
            }
            BOOL set = SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
            if (!set || GetLastError() != ERROR_SUCCESS) {
                // 设置权限失败
                cout << "提升权限失败 error:" << GetLastError() << endl;
                cout << "此文件夹缺少权限访问:    " << pathName.assign(path).append("\\").c_str() << endl;
                return;
            }
            // 权限设置成功,继续执行
            hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo);
            cout << "权限设置完成" << endl;
            cout << GetLastError()<<endl;
        }
        else
        {
            // 不是权限问题
            cout << "FindFirstFile failed " << GetLastError() << endl;
            system("pause");
            return;
        }
    }

    int flag = MY_NOT_CHECK;
    int lastError = 0;

    // 遍历
    do
    {
        //如果是文件夹,迭代之
        if ((fileinfo.dwFileAttributes &  FILE_ATTRIBUTE_DIRECTORY))
        {
            if (strcmp(fileinfo.cFileName, ".") != 0 && strcmp(fileinfo.cFileName, "..") != 0)
                getFiles(pathName.assign(path).append("\\").append(fileinfo.cFileName), exd, files);
        }
        else
        {
            //如果不是文件夹
            /*
            if (strcmp(fileinfo.cFileName, ".") != 0 && strcmp(fileinfo.cFileName, "..") != 0)
            {
                for (int i = 0; fileinfo.cFileName[i + 3] != '\0'; i++)
                {
                    // 判断是否exe
                    if (fileinfo.cFileName[i] == '.'
                        && (fileinfo.cFileName[i + 1] == 'e' || fileinfo.cFileName[i + 1] == 'E')
                        && (fileinfo.cFileName[i + 2] == 'x' || fileinfo.cFileName[i + 2] == 'X')
                        && (fileinfo.cFileName[i + 1] == 'e' || fileinfo.cFileName[i + 1] == 'E')
                        && fileinfo.cFileName[i + 4] == '\0')
                    {
                        files.push_back(fileinfo);
                        break;
                    }
                }
            }
            */
            // 如果当前目录还未查找过,查找当前目录的exe文件
            if (flag) 
            {
                // 关闭系统重定向
                if (Wow64DisableWow64FsRedirection(&OldValue))
                {
                    // 查找指定路径
                    hExe = FindFirstFile(pathName.assign(path).append("\\*." + exd).c_str(), &exeinfo);

                    if (FALSE == Wow64RevertWow64FsRedirection(OldValue))
                    {
                        return;
                    }
                }
                // hExe = FindFirstFile(pathName.assign(path).append("\\*.exe").c_str(), &exeinfo);
                if (hExe == INVALID_HANDLE_VALUE)
                {
                    lastError = GetLastError();
                    if (lastError == 2)
                    {
                        //cout << setiosflags(ios::left) << setw(50) << path << " 此目录下没有exe " << endl;
                    }
                    else
                    {
                        cout << " 查找exe失败 " << lastError << endl;
                        return;
                    }
                }
                // 遍历所有本文件夹下的exe文件
                if (lastError != 2)
                {
                    do
                    {
                        files.push_back(exeinfo);
                    } while (FindNextFile(hExe, &exeinfo));
                    // 查找完成,此目录已不用遍历,跳出
                    flag = MY_CHECKED;
                    FindClose(hExe);
                }
            }
        }
    } while (FindNextFile(hFile, &fileinfo));
    FindClose(hFile);
    return;
}










<think>嗯,用户问的是如何在C++14中获取指定路径下的指定类型文件名。我需要先回想一下C++标准库中有没有相关的功能。记得C++17引入了文件系统库,但用户指定的是C++14,所以不能使用std::filesystem。这样的话,可能需要用平台特定的方法,比如Windows的FindFirstFile/FindNextFile或者Linux的dirent.h。 首先,用户可能需要跨平台的解决方案,但C++14本身没有标准方法,所以得考虑平台相关的代码。或者有没有第三方库可以用?比如Boost.Filesystem,不过用户可能不想依赖第三方库。所以重点应该放在平台特定的实现上。 接下来,用户的需求是获取指定类型文件名,也就是扩展名匹配的文件。比如所有.txt文件。这时候需要遍历目录中的每个文件,检查扩展名是否符合要求。 在Windows下,用FindFirstFile和FindNextFile函数,配合WIN32_FIND_DATA结构体来遍历文件。然后对于每个文件,检查dwFileAttributes是否包含FILE_ATTRIBUTE_DIRECTORY来排除目录。再提取文件名,用PathFindExtension或者手动查找点号来获取扩展名,再和指定类型比较。 在Linux下,使用opendir和readdir函数,遍历目录项,同样需要检查文件类型,用stat或者d_type判断是否是普通文件。然后提取文件名的后缀,进行比较。 可能需要编写条件编译的代码,区分Windows和Linux的不同实现。用户可能需要一个示例代码,所以得准备两个平台的代码示例,或者写一个条件编译的示例。 还要注意Unicode的支持,比如在Windows下是否使用宽字符,但C++14中可能用char默认处理,或者使用TCHAR。但为了简单,可能使用窄字符,假设路径是ASCII的。 另外,错误处理也很重要,比如目录无法打开的情况,需要处理错误,但示例代码可能简化这一点,只给出基本逻辑。 总结步骤:遍历目录下所有文件,过滤掉子目录,检查文件扩展名是否符合,收集符合条件的文件名。需要分平台实现,并给出示例代码。</think>在 C++14 中获取指定路径下的指定类型文件名,可通过以下步骤实现(需要区分 Windows/Linux 平台): ```cpp #include <vector> #include <string> #ifdef _WIN32 #include <windows.h> // Windows 平台 #else #include <dirent.h> // Linux 平台 #endif std::vector<std::string> get_files_by_extension(const std::string& path, const std::string& ext) { std::vector<std::string> result; #ifdef _WIN32 // Windows 实现 WIN32_FIND_DATAA findData; HANDLE hFind = FindFirstFileA((path + "\\*" + ext).c_str(), &findData); if (hFind != INVALID_HANDLE_VALUE) { do { if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { result.emplace_back(findData.cFileName); } } while (FindNextFileA(hFind, &findData)); FindClose(hFind); } #else // Linux 实现 DIR* dir = opendir(path.c_str()); if (dir) { struct dirent* entry; while ((entry = readdir(dir)) != nullptr) { std::string filename(entry->d_name); if (filename.find(ext, filename.length() - ext.length()) != std::string::npos) { result.emplace_back(filename); } } closedir(dir); } #endif return result; } ``` 使用示例: ```cpp int main() { auto files = get_files_by_extension("D:/documents", ".txt"); for (const auto& f : files) { std::cout << f << std::endl; } return 0; } ``` 关键点说明: 1. 跨平台实现通过 `#ifdef` 区分系统 2. Windows 使用 `FindFirstFile/FindNextFile` API 3. Linux 使用 `opendir/readdir` 函数 4. 扩展名匹配通过字符串后缀比较实现 5. 自动过滤目录条目,只保留文件 注意: - 需要添加错误处理逻辑(示例代码已简化) - Windows 路径分隔符建议使用 `\\` - 扩展名匹配区分大小写(如需不区分需额外处理) - C++17 开始推荐使用 `<filesystem>` 标准库(但需符合 C++17 标准)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值