Boost :: filesystem that recursively gets the size of each file

Why does this code throw an error when the argument is a directory?

Using boost::recursive_directory_iterator

and using operators std::cout

, I see that it never prints the directory; only files. But, when I try to call boost::filesystem::file_size()

, the error comes up basically saying that I am trying to get the size of a file in a directory.

Error (argument "/ home" ):

terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
  what():  boost::filesystem::file_size: Operation not permitted: "/home/lost+found"
Aborted

      

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

namespace fs = boost::filesystem;

int main(int argc, char* argv[])
{
    if (argc != 2) return -1;

    const fs::path file{argv[1]};

    if (!fs::exists(file)) return -1;

    if (fs::is_regular_file(file))
        std::cout << file << "   [ " << fs::file_size(file) << " ]\n";

    else if (fs::is_directory(file))
        for (const fs::directory_entry& f : fs::recursive_directory_iterator{file})
            std::cout << f.path().filename() << "   [ " << fs::file_size(f.path()) << " ]\n";
}

      

Compiled with: g++ -Wall -Wextra -pedantic-errors -std=c++14 -lboost_system -lboost_filesystem -O2 -Os -s test3.cpp -o test3

+3


source to share


2 answers


You will receive an error:

call completion after calling instance 'boost :: filesystem :: filesystem_error' what (): boost :: filesystem :: file_size: operation not allowed: "/ home / lost + found" Canceled

This means that it cannot get the size of / home / lost + found. Usually lost + found folder and file_size

only get the size of regular files
.



I understand that the loop does not show the name of this folder. Perhaps this is because the compiler is evaluating fs::file_size(f.path())

and throwing a pre-call exception operator<<

for the filename so that it won't print.

I think the loop needs to be changed to check the regular file before asking for the size:

for (const fs::directory_entry& f : fs::recursive_directory_iterator{file}) {
  if (fs::is_regular_file(f.path()) {
    std::cout << f.path().filename() << "   [ " << fs::file_size(f.path()) << " ]\n";
  }
}

      

+2


source


Try to actually get the size recursively:

size_t du(fs::path p) {
    return fs::is_regular_file(p)
       ? file_size(p)
       : boost::accumulate(fs::directory_iterator{p}, 0ull, [](auto a, auto p){return a+du(p);});
}

      

This will work for directories by summing ( accumulate

) files in all base directories.

Live on coliru



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

namespace fs = boost::filesystem;
size_t du(fs::path p) {
    std::cout << __FUNCTION__ << "(" << p << ")\n";
    return fs::is_regular_file(p)
       ? file_size(p)
       : boost::accumulate(fs::directory_iterator{p}, 0ull, [](auto a, auto p){return a+du(p);});
}

int main(int argc, char* argv[])
{
    if (argc != 2) return -1;

    std::cout << "Size is " << du(argv[1]) << "\n";
}

      

With debug enabled std::cout

:

Size is du(".")
du("./main.cpp")
du("./a.out")
22435

      

+1


source







All Articles