一、项目背景详细介绍
在 C++ 实际工程开发中,**获取文件大小(字节数)**是一个极其基础、却又频繁出现的需求。
典型应用场景包括:
文件拷贝前判断大小
下载 / 上传进度计算
判断文件是否为空
限制文件最大尺寸
内存预分配(一次性读文件)
校验文件完整性
日志、CSV、二进制文件处理
断点续传与分块读写
虽然这是一个“看似简单”的问题,但在工程实践中,错误用法非常常见,例如:
以文本模式读取导致大小不准确
使用
tellg()却忘记移动到文件末尾大文件下使用
int发生溢出混淆“字符数”和“字节数”
因此,本项目将系统性讲解:
如何使用 C++ 标准库,安全、准确、跨平台地获取文件大小(字节数)
并给出工程中最推荐、最常用的实现方式。
二、项目需求详细介绍
2.1 功能性需求
输入文件路径
获取文件大小(单位:字节)
支持任意类型文件(文本 / 二进制)
支持大文件(> 4GB)
文件不存在时返回明确错误
2.2 非功能性需求
仅使用 C++ 标准库
不依赖第三方库
不使用系统 API
跨平台(Windows / Linux / macOS)
代码清晰、注释完整
教学与工程可复用
2.3 关键约束说明
⚠️ 本项目获取的是文件大小(字节数)
⚠️ 不是“字符数”
⚠️ 不受文件编码影响
三、相关技术详细介绍
3.1 字节数 vs 字符数
字节数(File Size)
文件在磁盘上占用的真实大小字符数(Character Count)
与编码相关(UTF-8 / UTF-16 / GBK)
示例:
| 内容 | 编码 | 字节数 |
|---|---|---|
ABC | ASCII | 3 |
中文 | UTF-8 | 6 |
中文 | UTF-16 | 4 |
➡️本项目只关心字节数
3.2 C++ 获取文件大小的几种方式对比
| 方法 | 是否推荐 | 说明 |
|---|---|---|
| 逐字节读取 | ❌ | 性能差 |
ifstream+tellg() | ✅ | 常用、可靠 |
seekg()+tellg() | ✅ | 工程推荐 |
<filesystem> | ⚠️ | C++17 才支持 |
⚠️ 为了与你前面系列代码风格统一,本项目采用文件流方式。
3.3seekg与tellg原理
seekg(pos):移动读指针tellg():返回当前读指针位置(字节偏移)
文件末尾位置 = 文件大小(字节)
四、实现思路详细介绍
整体实现流程如下:
以二进制模式打开文件
将读指针移动到文件末尾
使用
tellg()获取当前位置返回该值作为文件大小
恢复或关闭文件
该方案具有以下优点:
不读取文件内容
时间复杂度 O(1)
内存占用极低
支持超大文件
五、完整实现代码
/******************************************************** * 文件名:get_file_size.cpp * 功能:使用 C++ 文件流获取文件大小(字节数) * 说明: * 1. 使用 ifstream + seekg + tellg * 2. 二进制方式,不受编码影响 * 3. 支持任意类型文件与大文件 ********************************************************/ #include <iostream> #include <fstream> #include <string> /** * @brief 获取文件大小(字节数) * @param fileName 文件路径 * @return 文件大小(字节),失败返回 -1 */ long long getFileSize(const std::string& fileName) { // 以二进制方式打开文件 std::ifstream ifs(fileName, std::ios::binary); if (!ifs.is_open()) { return -1; } // 将读指针移动到文件末尾 ifs.seekg(0, std::ios::end); // 获取当前位置(即文件大小) std::streampos fileSize = ifs.tellg(); // 关闭文件 ifs.close(); // tellg() 返回的是 streampos,这里转换为 long long return static_cast<long long>(fileSize); } int main() { std::string fileName = "test.bin"; long long size = getFileSize(fileName); if (size < 0) { std::cout << "无法获取文件大小,文件可能不存在。" << std::endl; } else { std::cout << "文件:" << fileName << std::endl; std::cout << "文件大小:" << size << " 字节" << std::endl; } return 0; }六、代码详细解读(仅解读方法作用)
6.1getFileSize
以二进制方式打开文件
使用
seekg(0, end)移动到文件末尾使用
tellg()获取字节偏移返回文件大小
文件无法打开时返回
-1
6.2main函数
指定待检测文件
调用文件大小获取函数
输出文件大小结果
七、项目详细总结
通过本项目,你已经系统掌握:
文件大小与字符数的本质区别
为什么必须使用二进制模式
seekg/tellg的正确工程用法如何安全支持大文件
一个可复用的文件大小获取函数
该实现方案:
高效
稳定
跨平台
工程适用性极强
八、项目常见问题及解答
Q1:文本模式和二进制模式结果一样吗?
不一定。
Windows 下文本模式可能发生换行符转换。
Q2:为什么不用int返回大小?
int可能溢出(> 2GB)。
工程中必须使用long long。
Q3:对 UTF-8 / UTF-16 文件有影响吗?
没有。
返回的是字节数,与编码无关。
Q4:是否可以用于正在写入的文件?
可以,但获取的是当前时刻大小。