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

如何安全读取sysfs文件到缓冲区,无需两次打开文件句柄?

无需两次打开文件句柄读取sysfs文件到缓冲区的方法

你当前的代码通过两次打开sysfs文件来先获取大小再分配缓冲区,但确实可以只打开一次文件句柄,用动态扩容缓冲区的方式实现,完美适配sysfs文件无法用fseek()/stat()获取大小的场景。

优化后的代码示例

FILE *sysfs_file = fopen("/sys/file", "rb");
if (sysfs_file != NULL) {
    // 初始缓冲区大小,可根据sysfs文件的典型输出调整
    size_t buf_capacity = 128;
    char *buf = malloc(buf_capacity);
    if (buf == NULL) {
        fclose(sysfs_file);
        return; // 内存分配失败,自行处理后续逻辑
    }

    size_t current_length = 0;
    int ch;
    // 逐字符读取直到EOF
    while ((ch = fgetc(sysfs_file)) != EOF) {
        // 缓冲区已满,扩容(这里采用翻倍策略,平衡性能和内存)
        if (current_length >= buf_capacity) {
            size_t new_capacity = buf_capacity * 2;
            char *new_buf = realloc(buf, new_capacity);
            if (new_buf == NULL) {
                free(buf);
                fclose(sysfs_file);
                return; // 扩容失败,清理资源
            }
            buf = new_buf;
            buf_capacity = new_capacity;
        }
        buf[current_length++] = (char)ch;
    }

    // 追加字符串终止符,确保strstr等字符串函数能正常工作
    if (current_length >= buf_capacity) {
        char *new_buf = realloc(buf, buf_capacity + 1);
        if (new_buf == NULL) {
            free(buf);
            fclose(sysfs_file);
            return;
        }
        buf = new_buf;
    }
    buf[current_length] = '\0';

    // 原业务逻辑
    if (strstr(buf, "foo")) {
        printf("bar.\n");
    }

    // 清理资源
    free(buf);
    fclose(sysfs_file);
}

核心思路说明

  • 只打开一次文件句柄,避免两次读取可能出现的内容不一致(虽然sysfs文件通常稳定,但更严谨)
  • 初始分配一个合理的小缓冲区,读取过程中如果空间不足就用realloc动态扩容,无需预先知道文件大小
  • 最后必须手动添加'\0'终止符,因为fgetc不会自动添加,而strstr依赖C字符串的终止符
  • 全程处理内存分配/扩容失败的情况,避免内存泄漏或崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 04:24:18