如何一次性将6.32 GB文件读取到数组?ReadFile受限于DWORD
一次性读取6.32GB大文件到内存数组的解决方案
兄弟,你说的这个问题确实戳中了ReadFile的痛点——它的bytes_to_read参数是DWORD类型,也就是32位无符号整数,最大值大概是4.29GB,根本没法一次性装下6.32GB的文件。要搞定这种超大文件,最靠谱的办法是用Windows的内存映射文件(Memory-Mapped Files),这玩意儿能直接把整个大文件映射到你的进程虚拟内存里,你之后访问这块内存就跟访问普通数组一模一样,效率还贼高。
具体实现步骤与示例代码
我给你写个完整的可运行示例,步骤清晰明了:
- 用
CreateFile打开目标大文件,拿到合法的文件句柄 - 用
GetFileSizeEx获取64位的文件大小(毕竟超过4GB了,32位类型存不下) - 用
CreateFileMapping创建文件映射对象,参数天然支持64位文件尺寸 - 用
MapViewOfFile把文件映射到进程内存,得到的指针就是你要的"数组"起始地址 - 操作完成后按顺序释放资源,别漏了
#include <windows.h> #include <iostream> int main() { // 替换成你的目标文件路径 HANDLE hFile = CreateFile(L"your_6.32gb_file.bin", GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { std::cerr << "打开文件失败,错误码:" << GetLastError() << std::endl; return 1; } // 获取64位文件大小 LARGE_INTEGER fileSize; if (!GetFileSizeEx(hFile, &fileSize)) { std::cerr << "获取文件大小失败,错误码:" << GetLastError() << std::endl; CloseHandle(hFile); return 1; } // 创建文件映射对象 HANDLE hFileMapping = CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr); if (hFileMapping == nullptr) { std::cerr << "创建文件映射失败,错误码:" << GetLastError() << std::endl; CloseHandle(hFile); return 1; } // 将文件映射到进程内存空间 LPVOID pFileBuffer = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); if (pFileBuffer == nullptr) { std::cerr << "映射文件到内存失败,错误码:" << GetLastError() << std::endl; CloseHandle(hFileMapping); CloseHandle(hFile); return 1; } // 现在可以像操作普通数组一样访问文件内容了! // 示例:读取偏移量为1024的字节 unsigned char targetByte = static_cast<unsigned char*>(pFileBuffer)[1024]; std::cout << "偏移1024处的字节值:" << static_cast<int>(targetByte) << std::endl; // 按顺序释放资源,别搞反顺序 UnmapViewOfFile(pFileBuffer); CloseHandle(hFileMapping); CloseHandle(hFile); return 0; }
为啥不推荐分块调用ReadFile?
虽然你可以预先分配一个6.32GB的数组,然后多次调用ReadFile把文件内容一块块读进去,但这种方式不仅要自己写繁琐的分块逻辑,还会频繁在用户态和内核态之间拷贝数据,效率比内存映射差远了。内存映射是直接让操作系统帮你管理虚拟内存,按需加载文件内容到物理内存,既省事儿又高效。
重要提醒!
一定要把你的程序编译成64位版本!32位进程的虚拟内存空间最多也就4GB左右,根本装不下6.32GB的文件映射,只有64位程序才能搞定。而且内存映射不会一下子占满你的物理内存,操作系统会根据你访问的部分动态加载,不用担心内存不够用的问题。
内容的提问来源于stack exchange,提问作者John Deere
相关产品推荐
相关产品推荐

