如何安全读取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
相关产品推荐
相关产品推荐

