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

文件足够大时std::fread应成功?VS2015读取异常咨询

问题分析与解决方案

这不是Visual Studio 2015的Bug,而是误用文件打开模式导致的预期外行为,下面详细拆解原因和修复方法:

核心问题:文本模式与二进制模式的差异

你用L"r"(文本模式)打开了一个二进制格式的.data文件,而Windows平台的C标准库对文本模式有特殊处理逻辑:

  • 文本模式下,库会自动转换换行符(将\r\n转为\n)
  • 更关键的是,当读取到字节0x1A(DOS/Windows传统EOF标记,对应键盘Ctrl+Z)时,会被判定为文件结束,此时fread会停止读取,返回已读取的字节数,且errno保持为0——因为库认为这是正常的文本文件结束场景。

你的80MB文件恰好在第3473字节位置出现了0x1A字符,才会出现请求读取16384字节却仅返回3473字节的情况。

修复方法:使用二进制模式打开文件

处理二进制数据时,必须用二进制模式打开,只需将打开模式改为L"rb":

#include <cstdio>
#include <vector>
int main() {
    std::FILE* file;
    errno_t error = _wfopen_s(&file, L"/User/account/Desktop/file.data", L"rb");
    // 务必检查文件是否成功打开
    if (error != 0) {
        // 处理打开失败逻辑,比如打印错误信息
        return 1;
    }
    const std::size_t n = 16384;
    std::vector<unsigned char> v(n);
    const std::size_t nb_bytes_read = std::fread(v.data(), sizeof(unsigned char), n, file);
    // 现在只要文件剩余字节足够,就能读取到预期的16384字节
    std::fclose(file); // 别忘了关闭文件资源
    return 0;
}

补充说明

  • Unix/Linux平台上文本模式和二进制模式无差异,但为了跨平台兼容性,处理二进制文件时始终使用"rb"/"wb"等二进制模式是最佳实践。
  • C标准明确允许文本模式对输入输出进行特定转换(包括识别特殊EOF标记),所以这种行为是符合标准的,并非编译器或库的Bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:18:53