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

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

这个问题有许多重复(12345) ,但是它们在几十年前就被回答了。如今,这些问题中许多得票率很高的答案都是错误的。

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

  • H (包装器 Sprintstatf) ,使用 syscall

  • Tellg () ,根据定义返回一个 位置而不是 不一定是字节。返回类型不是 int

14563 次浏览

<filesystem> (added in C++17) makes this very straightforward.

#include <cstdint>
#include <filesystem>


// ...


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

As noted in comments, if you're planning to use this function to decide how many bytes to read from the file, keep in mind that...

...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 brings std::filesystem which streamlines a lot of tasks on files and directories. Not only you can quickly get file size, its attributes, but also create new directories, iterate through files, work with path objects.

The new library gives us two functions that we can use:

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


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

The first function is a free function in std::filesystem, the second one is a method in directory_entry.

Each method also has an overload, as it can throw an exception or return an error code (through an output parameter). Below is the detail code explaining all the possible cases.

#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';
}