boost версии 1.54 boost::filesystem::directory_iterator, Попытка использовать функцию is_directory

Использование Linux OpenSUSE 12.3 32-бит

Я просматриваю видеоролики Бартоша Милевски о параллелизме С++ 11 на YouTube. В части 5 он использует свой собственный файл filesystem.h в примере, где создается несколько потоков для чтения всех файлов в каталоге и его подкаталогах. Поэтому я решил использовать методы файловой системы boost, так как у меня нет к нему доступа. Я не могу понять, как вызвать is_directory для directory_iterator.

На самом деле у меня нет обычных методов для итератора каталогов. Я использую версию boost 1.54, загруженную с сайта. Я также использую Qt Creator (2.8.1), и его автозаполнение для directory_iterator не показывает никаких полезных функций. Я использовал boost для получения file_size() файла, поэтому я предполагаю, что он был установлен правильно. Я также взглянул на то, что устарело, и, похоже, ничего не нашел в directory_iterator.

я пробовал

itr.is_directory
*itr.is_directory
boost::filesystem::is_directory(itr->status())    //doesn't have the member function status
boost::filesystem::is_directory(boost::filesystem::status(itr))
itr.status();
itr->status();

Это код из примера Бартоша Милевски (еще не совсем законченный)

test2.cpp

#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono>
#include <vector>
#include <boost/filesystem.hpp>
typedef std::vector<std::string> string_vector;
namespace fs=boost::filesystem;
string_vector listDirectory(std::string && dir)
{
    string_vector listing;
    std::string dirStr("\n> ");
    dirStr += dir;
    dirStr += ":\n";
    listing.push_back(dirStr);

    std::vector<std::future<string_vector>> futures;
    for (fs::directory_iterator itr(dir); itr !=fs::directory_iterator(); ++itr)
    {  

если (itr.is_directory); здесь мне нужно узнать, является ли это каталогом

        {

        }
        else
        {

        }
    }
    return listing;
}

int main()
{
    std::string root= "/home/craig/";
    auto ftr = std::async(std::launch::async, &listDirectory, root);
    try
    {
        string_vector listing = ftr.get();

    }
}

автодополнение показывает следующее в Qt Creator (автозаполнение в скобках)

itr-> [mref, operator ->,operator Reference *,proxy]

person Craig    schedule 23.09.2013    source источник


Ответы (2)


Попробуйте так:

if (itr->status().type() == boost::filesystem::directory_file) {
    // ...
}
person user2802841    schedule 23.09.2013
comment
как я уже сказал, для directory_iterator нет функции состояния, так что это явно не сработает. - person Craig; 23.09.2013
comment
на самом деле я попробовал тупую программу, и статус, по-видимому, работает, извините за это. Так что на самом деле у меня есть вопрос о создателе qt, потому что он не использует ни одну из функций для автозаполнения ... что делает весь мой вопрос бессмысленным - person Craig; 23.09.2013
comment
Многие автодополнения часто дают сбои (или занимают много времени) в сложных библиотеках C++, код должен компилироваться очень хорошо, хотя, если он правильный. - person user2802841; 24.09.2013

хотя я не знаю, как заставить qt Creator автоматически заполнять файловую систему directory_iterator boost, я хотел опубликовать рабочий пример программы на случай, если кто-то еще окажется здесь. Также обратите внимание, что корень был изменен на /home/craig/Documents, так как каталог над ним привел к слишком большому количеству потоков для правильной работы (ресурс временно недоступен). Я думаю, что в следующей части (часть 6) Бартош ограничивает количество потоков, которые могут производиться.

#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono> //don't need this, for this program, but is in the example
#include <vector>
#include <boost/filesystem.hpp>

typedef std::vector<std::string> string_vector;
namespace fs=boost::filesystem;

string_vector listDirectory(std::string && dir)
{

    string_vector listing;
    std::string dirStr("\n> ");
    dirStr += dir;
    dirStr += ":\n";
    listing.push_back(dirStr);

    std::vector<std::future<string_vector>> futures;
    for (fs::directory_iterator itr(dir); itr !=fs::directory_iterator(); ++itr)
    {
        if (fs::is_directory(itr->status()))
        {

            auto ftr =std::async(std::launch::async,&listDirectory,std::move(itr->path().string()));
            futures.push_back(std::move(ftr));
        }
        else
        {
            listing.push_back(std::move(itr->path().filename().string()));
        }
    }
    for(auto &ftr:futures)
    {
        string_vector lst = ftr.get();
        std::move(lst.begin(),lst.end(),std::back_inserter(listing));

    }
    return listing;
}

int main()
{
    std::string root= "/home/craig/Documents/";
    auto ftr = std::async(std::launch::async, &listDirectory, std::move(root));
    try
    {
        string_vector listing = ftr.get();
        for (auto &s:listing)
        {
            std::cout << s << " ";
        }

    }
    catch(std::exception & e)
    {
        std::cout << e.what() << std::endl;
    }
    catch(...)
    {
        std::cout << "unknown exception" <<std::endl;
    }
}
person Craig    schedule 24.09.2013