Try like this:
if (itr->status().type() == boost::filesystem::directory_file) {
// ...
}
Pergunta
Using Linux OpenSUSE 12.3 32-bit
I'm going through Bartosz Milewski's c++11 concurrency videos on youtube. In part 5 he uses his own filesystem.h file in an example where multiple threads are spawned to read all the files in a directory and its sub-directories. So I decided to use boost's filesystem methods since I don't have access to his. I can't figure out how to call is_directory on a directory_iterator.
In fact I don't seem to have any of the regular methods for a directory iterator. I'm using boost version 1.54 downloaded source from site. I'm also using Qt Creator (2.8.1) and its auto-completion for a directory_iterator doesn't show any useful functions. I've used boost to get file_size() of a file, so I assume it was installed correctly. I've also taken a look at what was deprecated and can't seem to find anything on directory_iterator.
I've tried
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();
This is the code from Bartosz Milewski's example (not quite finished yet)
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)
{
if (itr.is_directory); this is where I need to find if its a 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();
}
}
auto-completion shows the following in Qt Creator (auto complete in brackets)
itr-> [mref, operator ->,operator Reference *,proxy]
Solução
Try like this:
if (itr->status().type() == boost::filesystem::directory_file) {
// ...
}
Outras dicas
while I don't know how to get qt creator to auto-complete boost's filesystem directory_iterator, I wanted to post the working example program in case someone else ends up here. Also note that root was changed to /home/craig/Documents since the directory above it resulted in too many threads to be able to run correctly ( Resource temporarily unavailable ) I think in the next part (part 6) Bartosz limits how many threads can be produced.
#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;
}
}