Create a Disk Usage Counter
Learn to create a disk usage counter.
We'll cover the following...
This is a simple utility that totals the size of every file in a directory and its sub-directories. It runs on both POSIX/Unix and Windows file systems.
How to do it
This recipe is a utility to report the size of every file in a directory and its sub-directories, along with a total. We'll re-use some of the functions we've used elsewhere in this chapter:
We start with a few convenience aliases:
namespace fs = std::filesystem;using dit = fs::directory_iterator;using de = fs::directory_entry;
We also use our
format
specialization forfs::path
objects:
template<>struct std::formatter<fs::path>: std::formatter<std::string> {template<typename FormatContext>auto format(const fs::path& p, FormatContext& ctx) {return format_to(ctx.out(), "{}", p.string());}};
For reporting the size of the directory, we'll use this
make_commas()
function:
string make_commas(const uintmax_t& num) {string s{ std::to_string(num) };for(long l = s.length() - 3; l > 0; l -= 3) {s.insert(l, ",");}return s;}
We've used this before. It inserts a comma before every third character from the end.
To sort our directory, we'll need a lowercase string function:
string strlower(string s) {auto char_lower = [](const char& c) -> char {if(c >= 'A' && c <= 'Z') return c + ('a' –'A');else return c;};std::transform(s.begin(), s.end(), s.begin(),char_lower);return s;}
We need a comparison predicate for sorting
directory_entry
objects by the lowercase of thepath
name:
bool dircmp_lc(const de& lhs, const de& rhs) {const auto lhstr{ lhs.path().string() };const auto rhstr{ rhs.path().string() };return strlower(lhstr) < strlower(rhstr);}