32

How should I use directory_iterator to list directory files (not recursive)?

Also what header files / libs should I add/link or other settings I should make? I'm using boost in my project but by some reason directory_iterator is "underclared identifier" while I can use other boost features.

Update

Another solution:

#include <filesystem>
#include <boost/filesystem.hpp>
#include <iostream>

using namespace boost::filesystem;

for (directory_iterator itr(path_ss); itr!=directory_iterator(); ++itr)
{
    cout << itr->path().filename() << ' '; // display filename only
    if (is_regular_file(itr->status())) cout << " [" << file_size(itr->path()) << ']';
    cout << '\n';
}
J. Calleja
  • 4,590
  • 2
  • 27
  • 50
Oleg Vazhnev
  • 21,122
  • 47
  • 154
  • 286

2 Answers2

60

The tut3 example is what you're looking for:

See it Live on Coliru

Here's a simplified version based on c++11:

Live On Coliru

#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>

using namespace boost::filesystem;

int main(int argc, char *argv[]) {
    path p(argc>1? argv[1] : ".");

    if(is_directory(p)) {
        std::cout << p << " is a directory containing:\n";

        for(auto& entry : boost::make_iterator_range(directory_iterator(p), {}))
            std::cout << entry << "\n";
    }
}

You can see I linked boost_system (for the errorcode facilities) and boost_filesystem:

g++ -std=c++11 -Os -Wall -pedantic main.cpp -lboost_system -lboost_filesystem && ./a.out .
"." is a directory containing:
"./main.cpp"
"./a.out"
sehe
  • 328,274
  • 43
  • 416
  • 565
  • 2
    This is a particular bad example as it does not focus directory_iterator and further used a lot of stream magic or std::copy. – Stefan Nov 17 '14 at 18:51
  • 8
    @Stefan That's fine logic if you discredit the standard library algorithms. Also, I was just referring to the tutorial (follow the link), in the good old spirit of [teach a man how to fish](http://en.wiktionary.org/wiki/give_a_man_a_fish_and_you_feed_him_for_a_day;_teach_a_man_to_fish_and_you_feed_him_for_a_lifetime). Finally, the answer was useful and has been accepted by the OP. I'm fine. (IOW _Your comment doesn't focus on the merit, but dwells on your own apparent confusion with mainstream c++ idioms. You are free to provide a simplified answer :)_) – sehe Nov 17 '14 at 20:01
  • By the way, there are many qualitities dubitable qualities in that example, Ironically, none of which you addressed. So, I simplified my answer code after all (but not the tut3, but you may create a pull request for that :)) – sehe Nov 17 '14 at 20:14
  • 4
    Thanks for introducing `make_iterator_range(foo, {})`, it's useful. – user31389 Mar 17 '17 at 12:28
  • New location: https://www.boost.org/doc/libs/1_71_0/libs/filesystem/doc/tutorial.html#Using-path-decomposition – kervin Oct 29 '19 at 17:41
8

A tested solution:

#include <boost/filesystem.hpp>
#include <iterator>
#include <iostream>
#include <vector>

using namespace boost::filesystem;

int main(int argc, char *argv[])
{
    path p(argc>1? argv[1] : ".");
    std::vector<directory_entry> v; // To save the file names in a vector.

    if(is_directory(p))
    {
        copy(directory_iterator(p), directory_iterator(), back_inserter(v));
        std::cout << p << " is a directory containing:\n";

        for ( std::vector<directory_entry>::const_iterator it = v.begin(); it != v.end();  ++ it )
        {
            std::cout<< (*it).path().string()<<endl;
        }    
    }
}
Adriaan
  • 555
  • 5
  • 20
Shaobo Zi
  • 659
  • 1
  • 8
  • 23
  • 3
    In what way was this more tested than the existing answer, posted almost 2 years earlier, which had a live demo even? – sehe Jan 28 '16 at 00:23
  • 1
    @sehe Indeed, I wouldn't say this one is more tested. Though it does conveniently save the file names in a vector, so that the file names can also be called later on, I guess. – Adriaan Jan 19 '17 at 19:03
  • It's always strictly more flexible to have an enumerate. You can always trivially chose to enumerate into a container. The other way around is impossible – sehe Jan 19 '17 at 19:07
  • @sehe Btw, do you perhaps know how I should modify this code in case I want to save the file names in a `vector` of `std::string`s instead of in a `vector` of `directory_entry`? Type casting the `directory_entry` to a `std::string` does not seem to work :(. – Adriaan Jan 19 '17 at 19:20