使用ifstream::read读取numpy格式二进制浮点数文件时读取字节数不符
问题根源:
ifstream::read的参数溢出 你遇到的核心问题是**std::ifstream::read的第二个参数类型是std::streamsize,而这个类型在多数系统上是32位有符号整数**。你要读取的总字节数是sizeof(float) * 3000*3000*249 = 8964000000字节,远大于32位有符号整数的最大值INT_MAX=2147483647,导致参数传递时发生溢出,read实际只读取了8964000000 % (INT_MAX+1) = 374065408字节(对应93516352个float),剩下的元素自然保持初始值0。
解决方案:分块读取大文件
通过分多次读取,每次读取不超过INT_MAX字节的内容,循环完成全部数据加载:
#include <iostream> #include <fstream> #include <vector> #include <climits> #include <algorithm> int main(){ std::ifstream ifs("fine_FA_S16_I000_recon.npy", std::ifstream::binary); ifs.seekg(128); // Skip header size_t nx = 3000, ny = 3000, nz = 249; size_t total_elements = nx*ny*nz; size_t total_bytes = total_elements * sizeof(float); std::vector<float> data(total_elements, 0); char* ptr = reinterpret_cast<char*>(&data[0]); size_t bytes_read = 0; const size_t chunk_size = static_cast<size_t>(INT_MAX); // 单次读取的最大安全字节数 while (bytes_read < total_bytes && ifs) { size_t bytes_to_read = std::min(chunk_size, total_bytes - bytes_read); ifs.read(ptr + bytes_read, static_cast<std::streamsize>(bytes_to_read)); bytes_read += ifs.gcount(); // 记录实际读取的字节数 } if (!ifs.eof()) { std::cerr << "读取文件时未到结尾就发生错误!" << std::endl; } size_t zeroes = std::count(data.begin(), data.end(), 0); std::cout << "Size of vector = " << data.size() << '\n'; std::cout << "Number of zeroes = " << zeroes << '\n'; std::cout << "INT_MAX = " << INT_MAX << '\n'; return 0; }
关键说明
- 用
bytes_read跟踪已读取的字节数,每次计算剩余待读取字节数,取INT_MAX和剩余值的较小值作为本次读取长度,避免参数溢出 - 使用
ifs.gcount()获取实际读取的字节数,应对文件提前结束等异常情况 - 增加读取状态检查,方便排查潜在的文件读取错误
内容的提问来源于stack exchange,提问作者John Barber
相关产品推荐
相关产品推荐

