如何使用 C++17 以字节为单位获取文件大小

How to get the file size in bytes with C++17

我应该知道特定操作系统是否存在陷阱?

这个问题有很多重复项 (1, 2, 3, , 5),但几十年前就有人回答了。许多这些问题中投票率很高的答案在今天是错误的。

.sx 上其他(旧 QA)的方法

<filesystem>(在 C++17 中添加)使得这个 very straightforward.

#include <cstdint>
#include <filesystem>

// ...

std::uintmax_t size = std::filesystem::file_size("c:\foo\bar.txt");

如评论中所述,如果您打算使用此函数来决定从文件中读取多少字节,请记住...

...unless the file is exclusively opened by you, its size can be changed between the time you ask for it and the time you try to read data from it.
– Nicol Bolas

C++17 带来了 std::filesystem,它简化了文件和目录上的许多任务。您不仅可以快速获取文件大小及其属性,还可以创建新目录、遍历文件、使用路径对象。

新库为我们提供了两个可以使用的函数:

std::uintmax_t std::filesystem::file_size( const std::filesystem::path& p );

std::uintmax_t std::filesystem::directory_entry::file_size() const;

第一个函数是std::filesystem中的一个自由函数,第二个是directory_entry中的一个方法。

每个方法都有重载,因为它可以抛出异常或 return 错误代码(通过输出参数)。 以下是解释所有可能情况的详细代码。

#include <chrono>
#include <filesystem>  
#include <iostream>

namespace fs = std::filesystem;

int main(int argc, char* argv[])
{
    try
    {
        const auto fsize = fs::file_size("a.out");
        std::cout << fsize << '\n';
    }
    catch (const fs::filesystem_error& err)
    {
        std::cerr << "filesystem error! " << err.what() << '\n';
        if (!err.path1().empty())
            std::cerr << "path1: " << err.path1().string() << '\n';
        if (!err.path2().empty())
            std::cerr << "path2: " << err.path2().string() << '\n';
    }
    catch (const std::exception& ex)
    {
        std::cerr << "general exception: " << ex.what() << '\n';
    }

    // using error_code
    std::error_code ec{};
    auto size = std::filesystem::file_size("a.out", ec);
    if (ec == std::error_code{})
        std::cout << "size: " << size << '\n';
    else
        std::cout << "error when accessing test file, size is: " 
              << size << " message: " << ec.message() << '\n';
}