boost :: filesystem以递归方式获取每个文件的大小

时间:2017-07-18 14:25:03

标签: c++ file boost filesystems boost-filesystem

为什么当参数是目录时,此代码会抛出错误?

使用boost::recursive_directory_iterator并使用std::cout语句,我可以看到它从不打印目录;只有文件。但是,当我尝试调用boost::filesystem::file_size()时,基本上会抛出一个错误,说我试图获取目录的文件大小。

错误(参数为" / 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";
}

编译:{{1​​}}

2 个答案:

答案 0 :(得分:3)

你得到的错误:

  

在抛出一个实例后终止调用   &#39;的boost ::文件系统:: filesystem_error&#39;什么():   boost :: filesystem :: file_size:不允许操作:   &#34; / home / lost + found&#34; 已中止

这意味着它无法获得 / home / lost + found 的大小。通常情况下, lost + found 是一个文件夹file_size only get the size of regular files

我知道循环不显示此文件夹的名称。这可能是因为编译器正在评估fs::file_size(f.path())并在为文件名调用operator<<之前抛出异常,因此它不会被打印出来。

我认为应该修改循环以在请求大小之前检查常规文件:

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";
  }
}

答案 1 :(得分:1)

尝试以递归方式获取大小:

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);});
}

这将通过对所有基础目录中的文件求和(accumulate)来对目录起作用。

<强> 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";
}

启用调试std::cout

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