首页 > 解决方案 > 为什么目录上的 std::filesystem::file_size 留给实现?

问题描述

所以我有以下问题:我需要总结特定目录中所有文件的字节大小,这包括子目录的大小,因为在我的情况下它们实际上可以增加大小。

但是如果我们在包含文件和子目录的目录上运行这段代码,看起来像这样:

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

int main(void)
{
    std::uintmax_t result = 0; 
    for (const auto& path : std::filesystem::directory_iterator("."))
    {
        result += std::filesystem::file_size(path)
    }

    std::cout << "Total size is: " << result << std::endl; 
    return 0;
}

然后你会得到一个错误,你正在尝试获取目录的文件大小。如果您在 macOS 或 Linux 上运行它,至少使用 Clang++ 10 或 11 进行编译。现在根据std::filesystem::file_size 上的 Cppreference获取目录的大小取决于实现。但是,在我看来,这很奇怪,因为 file_size 基本上只是“包装”统计信息,因此应该可以在目录上完美运行,至少在 Linux、*BSD 和 macOS 上是这样。

因此,任何人都可以启发我为什么将其留给实现,我可以访问 C++ 标准并且找不到充分的理由。

标签: c++std-filesystem

解决方案


目录的大小在不同平台上可能意味着不同的东西,甚至在同一平台上可能意味着不同的文件系统:可能是保存文件列表的磁盘分配的大小,或者目录中包含的文件数量,或者其他东西。在某些平台/文件系统上,可能没有有意义的易于访问的大小,因此可能会引发错误。

没有适用于所有地方的“目录大小”的通用定义,因此规范将其保留为实现定义。

确定一个目录使用了多少磁盘空间的正确方法是递归查找该目录中的文件并将它们的大小相加——但要注意:

  • 同一个文件的多个硬链接;您应该只计算一个,否则您将过度报告已用空间。
  • 表观尺寸与实际尺寸;稀疏文件的大小可能以 TB 为单位,但实际上只有几 KB 的已分配范围。
  • 符号链接;你会只计算它们自己的使用量,还是目标的使用量?

推荐阅读