Recipe – Recursively find specific files on Windows through C++ lambda expression

Hi Community,

I’m sorry for having been “absent” in the past few months, but I had been commuting (7 months)  interstate working on this important project for this department in federal government. I hope to catch up with the blogging and continue contributing as I have done in the past.

Today’s post is about a recipe I recently came up with whilst working on a personal project. The below code snippet allows traversing directory structures and finding specific files in Windows using a C++ lambda expression that’s recursively called.

 

std::vector<std::wstring> ProjectX::Core::Interop::GetSpecificFiles(std::wstring directoryPath, std::wstring extension) {

    std::vector<std::wstring> retval;

 

    auto getFileExt = [&](const std::wstring s) -> std::wstring {

        std::wstring retval;

        auto nPos = s.rfind('.', s.length());

 

        if (nPos != std::wstring::npos)

            retval = s.substr(nPos + 1, s.length() - nPos);

 

        return retval;

    };

    

    std::function<void(std::wstring)> fileEnum = [&](std::wstring path) -> void {

        WIN32_FIND_DATA fi;

        auto searchPattern = std::wstring(path.c_str()).append(L"*.*");

        auto found = FindFirstFile(searchPattern.c_str(), &fi);

 

        while (FindNextFile(found, &fi) != 0) {

            if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {

                if (wcscmp(fi.cFileName, L".") == 0 || wcscmp(fi.cFileName, L"..") == 0)

                    continue;

                else fileEnum(path + fi.cFileName + L"\"); // Call our lambda here to recurse directory structure

            }

            else if (getFileExt(fi.cFileName) == extension) {

                retval.push_back(path + fi.cFileName);

            }

        }

    };

 

    if (directoryPath.size() > 0 && extension.size() > 0) 

        fileEnum(directoryPath);

 

    return retval;

}

Leave a Reply

Your email address will not be published. Required fields are marked *