2017-10-05 157 views
0

我需要在目录中的文件夹列表,但只有文件夹。不需要文件。只有文件夹。我使用过滤器来确定这是否是一个文件夹,但它们不起作用并输出所有文件和文件夹。C++文件夹仅搜索

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); 

以这种方式,我检查它是一个文件夹。

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

如何解决问题?

+0

https://stackoverflow.com/questions/5043403/listing-only-folders-in-directory –

+1

发誓上的#include 和DIR – Xom9ik

+1

窗口当前不支持这一点。你可以['FindFirstFileEx'](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364419(v = vs.85).aspx)将* fSearchOp *设置为[“FindExSearchLimitToDirectories' ](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364416(v = vs.85).aspx) - 但此标志现在没有效果 – RbMm

回答

2

此功能收集文件夹到给定的载体。如果设置递归为true,将里面的文件夹进行扫描文件夹中的文件夹等

// 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); 
} 

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

2

修改有两种方法可以做到这一点:难的方法和简单的方法。

难的方法是基于FindFirstFileFindNextFile,根据需要过滤掉的目录。你会发现一个bazillion样本,规定了这种做法,无论是在堆栈溢出以及互联网的休息。

简单的方法:使用标准directory_iterator类(或recursive_directory_iterator,如果需要递归到子目录中)。该解决方案很简单,只要:

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

你将不得不包括<filesystem>头文件,在C++ 17导入。

注意:使用最新版本的Visual Studio 2017(15.3.5),这还没有在namespace std。您必须改为参考namespace std::experimental::filesystem


请特别注意,没有必要过滤掉...伪目录;这些不是由目录迭代器返回的。