2017-10-05 155 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


請特別注意,沒有必要過濾掉...僞目錄;這些不是由目錄迭代器返回的。