c++如何获取文件大小_c++ filesystem获取文件字节数【常用】

6次阅读

std::Filesystem::file_size可直接获取文件大小(字节数),需c++17+、头文件,注意捕获filesystem_error异常,并支持symlink_option::nofollow选项。

c++如何获取文件大小_c++ filesystem获取文件字节数【常用】

std::filesystem::file_size 最直接

C++17 起,std::filesystem 提供了标准、跨平台的获取方式。只要路径有效且可访问,std::filesystem::file_size 就返回字节数(std::uintmax_t 类型)。

  • 必须包含头文件:#include ,并启用 C++17 或更高标准(如编译时加 -std=c++17
  • 需处理异常:路径不存在、无权限、是目录而非文件等情况会抛出 std::filesystem::filesystem_error
  • 注意:对符号链接默认解析目标文件大小;若要获取链接本身元数据,需传入 std::filesystem::symlink_option::nofollow
try {     auto size = std::filesystem::file_size("data.bin");     std::cout << "Size: " << size << " bytesn"; } catch (const std::filesystem::filesystem_error& e) {     std::cerr << "Error: " << e.what() << "n"; }

windows 下用 GetFileSizeEx 更底层但可控

当需要绕过 std::filesystem 的异常机制,或在旧标准(C++11/14)环境下工作时,Windows API 是可靠选择。

  • GetFileSizeEx 返回 bool,成功时通过 LARGE_INTEGER* 输出 64 位大小,能正确处理 >4GB 文件
  • 必须先用 CreateFile 打开文件,且权限至少含 GENERIC_READFILE_READ_ATTRIBUTES
  • 别忘了调用 CloseHandle,否则资源泄漏;打开失败时句柄为 INVALID_HANDLE_VALUE
HANDLE h = CreateFile(L"input.txt", FILE_READ_ATTRIBUTES,                       FILE_SHARE_READ, nullptr, OPEN_EXISTING,                       FILE_ATTRIBUTE_NORMAL, nullptr); if (h != INVALID_HANDLE_VALUE) {     LARGE_INTEGER size;     if (GetFileSizeEx(h, &size)) {         std::cout << "Size: " << size.QuadPart << " bytesn";     }     CloseHandle(h); }

POSIX 环境下用 statfstat

linux/macos 等系统中,stat 是最常用方式,尤其适合已知文件路径的场景;若已有打开的文件描述符,则用 fstat 避免重复 open。

  • stat 填充 Struct stat,其中 st_size 字段即文件字节数(对常规文件有效)
  • 注意:st_size 对管道、设备文件等可能无意义;对稀疏文件它返回逻辑大小,非磁盘实际占用
  • 调用后检查返回值,-1 表示失败(如路径不存在、权限不足),错误码在 errno
struct stat sb; if (stat("log.txt", &sb) == 0) {     std::cout << "Size: " << sb.st_size << " bytesn"; } else {     perror("stat"); }

为什么不用 seekg + tellg

有人尝试用 std::ifstreamseekg(0, std::ios::end)tellg() 来“测长度”,这在多数情况下看似可行,但有明显缺陷:

立即学习C++免费学习笔记(深入)”;

  • 对二进制文件,某些平台(尤其是 Windows)文本模式打开会导致 rn 转换干扰位置计算
  • 流状态可能被其他操作污染(如之前读取失败置位 failbit),tellg() 返回 -1
  • 不适用于只读不可 seek 的文件(如 FIFO、/proc 文件等),且打开开销比元数据查询大
  • 不是原子操作:两次 I/O 调用之间文件可能被截断或扩展

除非你明确在操作一个已打开、可 seek 的流且只关心其当前长度,否则优先用文件系统接口而非流定位。

text=ZqhQzanResources