C++之获取文件大小(跨平台)

这篇博客介绍了如何在C++中实现跨平台获取文件大小的方法,适用于Windows和Linux环境,通过使用特定的结构体和包含相关头文件来实现。

C/C++、Window、Linux 环境都可以使用!

通过结构体struct stat获得。

需要包含头文件:#include <sys/stat.h> // struct stat

// 通过stat结构体 获得文件大小,单位字节
size_t getFileSize1(const char *fileName) {

	if (fileName == nullptr) {
		return 0;
	}
	
	// 这是一个存储文件(夹)信息的结构体,其中有文件大小和创建时间、访问时间、修改时间等
	struct stat statbuf;

	// 提供文件名字符串,获得文件属性结构体
	stat(fileName, &statbuf);
	
	// 获取文件大小
	size_t filesize = statbuf.st_size;

	return filesize;
}

原文链接:C++之获取文件大小(跨平台)-优快云博客

<think>好的,我现在需要解决用户的问题:寻找一个跨平台C++函数来获取超过2GB的大文件大小,因为传统的fseek和ftell可能存在限制。用户之前的问题是关于大文件操作的替代方案,所以这次需要结合之前的回答,并参考用户提供的引用内容,但用户也指出引用仅供参考,主要应关注当前的问题。 首先,回顾之前给出的解决方案,用户已经提到了在Linux下使用stat的st_size,Windows下可能使用_fseeki64或_ftelli64,以及跨平台的fgetpos/fsetpos和内存映射。但用户现在特别需要跨平台C++函数,所以可能需要整合不同平台的特性,同时确保兼容性。 用户提到C++,可能需要用C++标准库或跨平台的方法,而不是纯C的方法。同时,用户希望避免使用平台特定的函数,如Linux的stat或Windows的特定函数,所以需要考虑如何统一处理。 可能的思路: 1. 使用C++17引入的std::filesystem库,这是跨平台的,可以获取文件大小。但需要确认是否支持大文件(超过2GB)。查阅资料,std::filesystem::file_size返回的是uintmax_t,通常足够大,可以处理大文件,但需要确认在不同平台下的实现是否确实支持64位文件大小。 2. 如果用户不能使用C++17,可能需要回退到平台特定的方法,并用预处理指令区分不同平台,比如#ifdef _WIN32,然后使用Windows的GetFileSizeEx,而在其他平台使用stat。 3. 另外,用户之前的回答中提到了stat函数,但那是C语言的,用户现在可能需要C++的封装方法。或者,在C++中调用这些C函数,但封装成跨平台函数。 需要验证std::filesystem是否可靠处理大文件。例如,在Windows和Linux下,std::filesystem::file_size是否内部使用64位的结构。比如,在Windows下,它可能调用GetFileSizeEx,而Linux下使用stat64,这些都支持大文件。 同时,检查C++17的兼容性,如果用户的环境支持C++17或更高版本,那么推荐使用std::filesystem是最简洁的跨平台方案。否则,需要手动封装。 另一个可能性是使用boost::filesystem,如果用户允许使用Boost库的话,但用户可能更倾向于标准库解决方案。 此外,用户之前的回答中提到了stat结构中的st_size是off_t类型,在定义了_FILE_OFFSET_BITS=64的情况下,off_t是64位的。所以在C++中,可以同样使用stat,但需要确保正确的编译选项。 现在需要将这些思路整理成一个清晰的回答,说明跨平台的几种方法,包括使用C++17标准库,或者条件编译调用平台特定API,或者使用stat函数配合宏定义。 还需要注意编译选项,如在Linux下需要定义_FILE_OFFSET_BITS=64,以确保off_t是64位的。 可能还需要处理错误情况,比如文件不存在时的异常处理,或者返回类型是否足够大。 现在,组织回答的结构: 1. 推荐使用C++17的std::filesystem::file_size,并说明其优点,以及如何检测文件是否存在等。 2. 如果无法使用C++17,则提供跨平台的条件编译方法,使用stat或GetFileSizeEx,并处理宏定义。 3. 强调编译时的注意事项,比如在Linux下需要定义_FILE_OFFSET_BITS=64。 4. 给出代码示例,并说明如何处理大文件。 另外,引用用户之前的回答中的内容,比如之前提到的stat函数,但需要转换为C++的用法,或者提到之前的回答中的解决方案如何在此处适用。 最后,确保回答中提到的函数是跨平台的,并且能够处理超过2GB的文件,同时避免使用已被指出有问题的fseek/ftell方法。 可能还需要验证不同平台下std::filesystem::file_size的表现,比如在32位系统下是否仍能正确处理大文件,但根据C++标准,uintmax_t应该是足够大的类型,但实际实现可能依赖于平台的支持。但一般来说,主流编译器在64位系统上会支持大文件。 总结:最佳跨平台方案是使用C++17的std::filesystem,若不可用,则使用条件编译调用平台特定的API,并确保正确的编译选项。</think>### 跨平台获取文件大小C++解决方案 针对超过2GB的大文件,传统`fseek`/`ftell`存在32位偏移量限制,以下是**跨平台兼容**且支持超大文件的实现方案: --- #### 一、C++17标准方案(推荐) 使用`std::filesystem`库(需C++17或更高版本),直接获取文件大小: ```cpp #include <filesystem> #include <iostream> namespace fs = std::filesystem; int main() { try { fs::path file_path = "large_image.img"; if (fs::exists(file_path)) { uintmax_t size = fs::file_size(file_path); // 自动支持64位文件大小 std::cout << "文件大小: " << size << " 字节" << std::endl; } else { std::cerr << "文件不存在" << std::endl; } } catch (const fs::filesystem_error& e) { std::cerr << "错误: " << e.what() << std::endl; } return 0; } ``` - **优势** - 完全跨平台,无需平台特定代码 - 类型`uintmax_t`可表示最大文件尺寸(64位系统为128位)[^1] --- #### 二、兼容旧标准的跨平台实现 若无法使用C++17,可通过条件编译整合系统API: ```cpp #include <iostream> #include <cstdio> #ifdef _WIN32 #include <windows.h> #else #include <sys/stat.h> #include <unistd.h> #endif long long get_file_size(const char* filename) { #ifdef _WIN32 // Windows: 使用GetFileSizeEx支持64位 HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return -1; LARGE_INTEGER size; if (!GetFileSizeEx(hFile, &size)) { CloseHandle(hFile); return -1; } CloseHandle(hFile); return size.QuadPart; #else // Linux/Unix: 使用stat并定义_FILE_OFFSET_BITS=64 struct stat st; if (stat(filename, &st) != 0) return -1; return static_cast<long long>(st.st_size); // st_size为off_t(64位) #endif } int main() { const char* filename = "large_image.img"; long long size = get_file_size(filename); if (size >= 0) { std::cout << "文件大小: " << size << " 字节" << std::endl; } else { std::cerr << "获取文件大小失败" << std::endl; } return 0; } ``` --- #### 三、关键注意事项 1. **Linux/Unix编译参数** 需在编译时启用大文件支持: ```bash g++ -D_FILE_OFFSET_BITS=64 -o program source.cpp ``` - 确保`off_t`类型为64位,支持EB级文件[^3] 2. **Windows兼容性** - `GetFileSizeEx`直接返回64位大小,无需额外配置 3. **错误处理** - 文件不存在、权限不足等情况需显式处理 --- #### 四、性能对比 | 方法 | 适用场景 | 优点 | 缺点 | |---------------------|---------------------------|-------------------------------|-----------------------| | `std::filesystem` | C++17及以上项目 | 代码简洁,零依赖 | 需现代编译器支持 | | 条件编译 | 兼容旧代码/跨C/C++项目 | 支持所有C++标准 | 需维护平台特定逻辑 | --- ### 相关问题 1. 如何在C++中高效读取超过4GB的二进制文件? 2. 文件内存映射(mmap)在Windows和Linux下的实现差异? 3. 为什么32位系统无法直接处理超过4GB的文件? [^1]: `std::filesystem`内部使用系统原生API实现文件操作 [^3]: `stat`函数通过`_FILE_OFFSET_BITS=64`启用64位文件支持
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吉特哈布

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值