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

fread读取二进制文件抛出异常,已确认fileSize正确,求修正方案

问题分析与修复方案

你的readFile函数在调用fread时出现崩溃(你描述的“抛出异常”在C中通常指段错误或信号触发的程序终止),结合你提到fileSize能正确获取文件字节数,以下是问题原因和修复步骤:

可能的核心原因

  1. 错误判断不精准:fread返回字节数小于fileSize时,可能是读取过程中发生了权限问题、文件被锁定等错误,而非单纯到达文件末尾,原代码未区分这两种情况。
  2. fseek+ftell的兼容性局限:对于部分特殊文件(如管道、设备文件),fseek(SEEK_END)的行为未定义,虽然你确认fileSize正确,但这种方式本身存在隐性风险。
  3. 内存分配的隐性问题:部分系统开启内存过度提交后,malloc可能返回非空指针但实际内存不足,导致fread写入时触发内存错误。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>

static char* readFile(const char* path) {
    FILE* file = fopen(path, "rb");
    if (!file) {
        fprintf(stderr, "无法打开文件 \"%s\":%s\n", path, strerror(errno));
        exit(1);
    }

    // 用fstat替代fseek+ftell,更可靠获取文件大小
    struct stat st;
    if (fstat(fileno(file), &st) == -1) {
        fprintf(stderr, "获取文件大小失败 \"%s\":%s\n", path, strerror(errno));
        fclose(file);
        exit(1);
    }
    size_t fileSize = st.st_size;

    char* buffer = malloc(fileSize + 1); // sizeof(char)恒为1,可省略
    if (!buffer) {
        fprintf(stderr, "内存不足,无法读取文件 \"%s\"\n", path);
        fclose(file);
        exit(1);
    }

    size_t bytesRead = fread(buffer, 1, fileSize, file);
    // 区分读取错误与文件提前结束
    if (bytesRead < fileSize) {
        if (ferror(file)) {
            fprintf(stderr, "读取文件 \"%s\" 出错:%s\n", path, strerror(errno));
        } else {
            fprintf(stderr, "文件 \"%s\" 提前结束,未读取完整\n", path);
        }
        free(buffer);
        fclose(file);
        exit(1);
    }
    buffer[bytesRead] = '\0';
    
    fclose(file);
    return buffer;
}

关键修复点

  • 替换文件大小获取方式:fstat通过文件描述符直接读取系统元数据,避免了fseek对特殊文件的兼容性问题,结果更可靠。
  • 细化错误处理:用ferror(file)区分读取错误和文件提前结束的场景,结合strerror(errno)输出具体错误信息,方便定位问题。
  • 避免内存泄漏:读取失败时及时释放已分配的内存,再关闭文件退出。
  • 简化代码:省略冗余的sizeof(char),因为C标准定义其值恒为1。

额外排查建议

  1. 确认目标文件的读取权限,确保当前进程有权限访问该文件。
  2. 若处理超大文件(超过long类型范围),ftell会返回错误,但stat的st_size在64位系统中支持更大的文件尺寸。
  3. 检查系统内存配置,若存在内存过度提交导致的虚假分配问题,可调整系统参数或增加可用内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:53:10