c++ folder only search

戏子无情 提交于 2019-12-13 03:51:14

问题


I need to get a list of folders in the directory, but only the folders. No files are needed. Only folders. I use filters to determine if this is a folder, but they do not work and all files and folders are output.

string root = "D:\\*";
cout << "Scan " << root << endl;
std::wstring widestr = std::wstring(root.begin(), root.end());
const wchar_t* widecstr = widestr.c_str();
WIN32_FIND_DATAW wfd;
HANDLE const hFind = FindFirstFileW(widecstr, &wfd);

In this way, I check that it is a folder.

if (INVALID_HANDLE_VALUE != hFind)
    if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))

How to solve a problem?


回答1:


This function collects folders into given vector. If you set recursive to true, it will be scanning folders inside folders inside folders etc.

// TODO: proper error handling.

void GetFolders( std::vector<std::wstring>& result, const wchar_t* path, bool recursive )
{
    HANDLE hFind;
    WIN32_FIND_DATA data;
    std::wstring folder( path );
    folder += L"\\";
    std::wstring mask( folder );
    mask += L"*.*";

    hFind=FindFirstFile(mask.c_str(),&data);
    if(hFind!=INVALID_HANDLE_VALUE)
    {
        do
        {
            std::wstring    name( folder );
            name += data.cFileName;
            if ( ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
                 // I see you don't want FILE_ATTRIBUTE_REPARSE_POINT
                 && !( data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) )
            {
                // Skip . and .. pseudo folders.
                if ( wcscmp( data.cFileName, L"." ) != 0 && wcscmp( data.cFileName, L".." ) != 0 )
                {
                    result.push_back( name );
                    if ( recursive )
                        // TODO: It would be wise to check for cycles!
                        GetFolders( result, name.c_str(), recursive );
                }
            }
        } while(FindNextFile(hFind,&data));
    }
    FindClose(hFind);
}

Modified from https://stackoverflow.com/a/46511952/8666197




回答2:


There are two ways to do this: The hard way, and the easy way.

The hard way is based on FindFirstFile and FindNextFile, filtering out directories as needed. You will find a bazillion samples that outline this approach, both on Stack Overflow as well as the rest of the internet.

The easy way: Use the standard directory_iterator class (or recursive_directory_iterator, if you need to recurse into subdirectories). The solution is as simple as1:

for ( const auto& entry : directory_iterator( path( L"abc" ) ) ) {
    if ( is_directory( entry.path() ) ) {
        // Do something with the entry
        visit( entry.path() );
    }
}

You will have to include the <filesystem> header file, introduced in C++17.

Note: Using the latest version of Visual Studio 2017 (15.3.5), this is not yet in namespace std. You will have to reference namespace std::experimental::filesystem instead.


1Note in particular, that there is no need to filter out the . and .. pseudo-directories; those aren't returned by the directory iterators.

来源:https://stackoverflow.com/questions/46588859/c-folder-only-search

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!