std::filesystem::space(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’Ύ NAME πŸ’Ύ

std::filesystem::space β€” std::filesystem::space. Okay bestie, welcome to the std::filesystem::space(3) page from the C++ Standard Libary manual (yes, that spelling is literally right there in the archives; we respect the texts πŸ’…). This is the function that checks out a filesystem's space situation.

✨ Synopsis ✨

The official synopsis is giving very "manual page layout" energy β€” line breaks doing the absolute most β€” but here it is, exactly:

          Defined in header <filesystem>
          std::filesystem::space_info space( const std::filesystem::path& p
       (1) (since C++17)
          );
          std::filesystem::space_info space( const std::filesystem::path& p,
       (2) (since C++17)
                                             std::error_code& ec ) noexcept;

Overload (1) is since C++17. Overload (2) is also since C++17 and is noexcept. Slay.

So what does it do? It determines the information about the filesystem on which the pathname p is located, as if by POSIX statvfs.

It populates and returns an object of type filesystem::space_info, set from the members of the POSIX struct statvfs as follows:

  • space_info.capacity is set as if by f_blocks * f_frsize.
  • space_info.free is set to f_bfree * f_frsize.
  • space_info.available is set to f_bavail * f_frsize.
  • Any member that could not be determined is set to static_cast<std::uintmax_t>(-1).

The non-throwing overload sets all members to static_cast<std::uintmax_t>(-1) on error. Not me getting emotional over sentinel values 😭.

🌸 Parameters 🌸

  • p β€” path to examine πŸ‘€
  • ec β€” out-parameter for error reporting in the non-throwing overload.

🫢 Return value 🫢

The filesystem information (a filesystem::space_info object). That's it, that's the gift.

😭 Exceptions 😭

Any overload not marked noexcept may throw std::bad_alloc if memory allocation fails. Allocation failure really said "let me ruin the vibe" πŸ’€.

  1. Throws std::filesystem::filesystem_error on underlying OS API errors, constructed with p as the first path argument and the OS error code as the error code argument.
  2. Sets a std::error_code& parameter to the OS API error code if an OS API call fails, and executes ec.clear() if no errors occur.

πŸ¦‹ Notes πŸ¦‹

space_info.available may be less than space_info.free. Yep, that's a thing; it's literally in the docs, no cap.

πŸŽ€ Example πŸŽ€

       // Run this code

        #include <cstdint>
        #include <filesystem>
        #include <iostream>

        std::uintmax_t disk_usage_percent(const std::filesystem::space_info&
       si,
                                          bool is_privileged = false) noexcept
        {
            if (constexpr std::uintmax_t X(-1);
                si.capacity == 0 || si.free == 0 || si.available == 0 ||
                si.capacity == X || si.free == X || si.available == X
            )
                return 100;

            std::uintmax_t unused_space = si.free, capacity = si.capacity;
            if (!is_privileged)
            {
                const std::uintmax_t privileged_only_space = si.free -
       si.available;
                unused_space -= privileged_only_space;
                capacity -= privileged_only_space;
            }
            const std::uintmax_t used_space{capacity - unused_space};
            return 100 * used_space / capacity;
        }

        void print_disk_space_info(auto const& dirs, int width = 14)
        {
            (std::cout << std::left).imbue(std::locale("en_US.UTF-8"));

            for (const auto s : {"Capacity", "Free", "Available", "Use%",
       "Dir"})
                std::cout << "β”‚ " << std::setw(width) << s << ' ';

            for (std::cout << '\n'; auto const& dir : dirs)
            {
                std::error_code ec;
                const std::filesystem::space_info si =
       std::filesystem::space(dir, ec);
                for (auto x : {si.capacity, si.free, si.available,
       disk_usage_percent(si)})
                    std::cout << "β”‚ " << std::setw(width) <<
       static_cast<std::intmax_t>(x) << ' ';
                std::cout << "β”‚ " << dir << '\n';
            }
        }

        int main()
        {
            const auto dirs = {"/dev/null", "/tmp", "/home", "/proc", "/null"};
            print_disk_space_info(dirs);
        }

πŸ–₯️ Possible output πŸ–₯️

        β”‚ Capacity       β”‚ Free           β”‚ Available      β”‚ Use%           β”‚
       Dir
        β”‚ 84,417,331,200 β”‚ 42,732,986,368 β”‚ 40,156,028,928 β”‚ 50             β”‚
       /dev/null
        β”‚ 84,417,331,200 β”‚ 42,732,986,368 β”‚ 40,156,028,928 β”‚ 50             β”‚
       /tmp
        β”‚ -1             β”‚ -1             β”‚ -1             β”‚ 100            β”‚
       /home
        β”‚ 0              β”‚ 0              β”‚ 0              β”‚ 100            β”‚
       /proc
        β”‚ -1             β”‚ -1             β”‚ -1             β”‚ 100            β”‚
       /null

πŸ‘‘ See also πŸ‘‘

  • space_info β€” information about free and available space on the filesystem (C++17) (class).

mwah πŸ’‹ source: cppreference.com Β· dated 2024.06.10 Β· page: std::filesystem::space(3). go check ur disk space and slay, bestie 🫢✨

πŸ“¦ where this page comes from