You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中如何将二进制文件读取到vector?data未填充问题求解

二进制文件读取至vector失败的问题修复

核心问题与修复要点

  • vector内存预留不等于元素创建
    你使用data.reserve(totalElements)仅为vector预留了内存空间,但vector的实际元素数量(size)仍为0。此时访问data[offset]属于越界访问,是未定义行为,数据根本无法写入到vector的有效元素区域。
    解决:将reserve替换为resize(totalElements),该操作会直接创建totalElements个DataArray元素,同时分配对应内存,后续read操作可直接写入到有效内存地址。

  • 文件打开失败未终止流程
    文件打开失败后仅输出错误信息,但后续的seekg、tellg等操作仍会执行,这些操作在无效流上会直接出错,导致后续计算全部失效。
    解决:在输出错误后添加return,直接终止函数。

  • 文件大小与元素大小的匹配检查
    若文件大小不是sizeof(DataArray)的整数倍,计算totalElements时会丢弃末尾不完整的元素,建议添加检查提示,避免静默错误。

  • 读取操作后的状态校验
    每次read后需检查流状态,确认数据是否成功读取,避免读取失败却未被发现的情况。


修复后的完整代码

#include <fstream>
#include <vector>
#include <cerrno>
#include <cstring>

void loadDataFromFile(const std::string& filePath, std::vector<DataArray>& data) 
{
    std::ifstream inFile(filePath, std::ios::binary);
    if (!inFile) {
        std::cerr << "Error opening file! " << std::strerror(errno) << std::endl;
        return; // 打开失败直接终止
    }
    
    // 获取文件大小
    inFile.seekg(0, std::ios::end);
    std::streampos file_pos = inFile.tellg();
    if (file_pos == std::streampos(-1)) {
        std::cerr << "Failed to get file size!" << std::endl;
        inFile.close();
        return;
    }
    std::streamsize file_size = file_pos;
    inFile.seekg(0, std::ios::beg);

    constexpr std::size_t bufferSize = 700 * 1024 * 1024; // 700 MB buffer size

    std::size_t elementSize = sizeof(DataArray);
    if (elementSize == 0) {
        std::cerr << "Invalid DataArray size!" << std::endl;
        inFile.close();
        return;
    }

    // 检查文件大小是否为元素大小的整数倍
    if (file_size % elementSize != 0) {
        std::cerr << "File size does not match element size multiple! Remaining bytes: " 
                  << file_size % elementSize << std::endl;
    }
    std::size_t totalElements = static_cast<std::size_t>(file_size) / elementSize;

    data.resize(totalElements); // 关键:创建元素而非仅预留内存
    
    std::size_t offset = 0;
    while (offset < totalElements) {
        std::size_t count = std::min(bufferSize / elementSize, totalElements - offset);

        inFile.read(reinterpret_cast<char*>(&data[offset]), count * elementSize);

        // 校验读取状态
        if (!inFile) {
            std::cerr << "Failed to read file at offset " << offset << ". Read " << inFile.gcount() << " bytes." << std::endl;
            break;
        }

        offset += count;
    }

    inFile.close();
}

内容的提问来源于stack exchange,提问作者Schtraded

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 19:40:04