如何正确读取/proc/cmdline文件大小?代码存指针警告与乱码问题
问题分析与解决
首先,你代码里的第一个问题是fstat(file, &st)的类型不匹配:fstat()的第一个参数要求是文件描述符(int类型),而非FILE*指针,所以编译器会抛出类型转换警告。改成fstat(fileno(file), &st)是正确的类型修正,但这又引出新问题——根源在于/proc/cmdline是内核虚拟文件,这类文件的st_size字段完全不可靠。
/proc目录下的文件并非真实存储在磁盘上,而是内核在程序发起读取请求时才动态生成内容的虚拟节点,fstat()拿到的st_size往往是无效值(比如你看到的01315,这是内核返回的无意义数值,并非真实内容长度),用它定义缓冲区大小必然导致读取异常,出现乱码。
正确实现方式
不需要预先获取文件大小,直接用足够大的静态缓冲区(内核启动参数长度不会特别大,1024字节足以覆盖绝大多数场景),或者用动态扩容的方式读取:
静态缓冲区实现(简单高效)
#include <stdio.h> #include <unistd.h> int main() { FILE *file = fopen("/proc/cmdline", "r"); if (!file) { perror("fopen failed"); return 1; } char buffer[1024]; if (fgets(buffer, sizeof(buffer), file)) { printf("%s\n", buffer); } else { perror("fgets failed"); } fclose(file); return 0; }
动态扩容实现(兼容极端超长场景)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main() { FILE *file = fopen("/proc/cmdline", "r"); if (!file) { perror("fopen failed"); return 1; } size_t buf_size = 256; char *buffer = malloc(buf_size); if (!buffer) { perror("malloc failed"); fclose(file); return 1; } size_t total_read = 0; char *temp; while (fgets(buffer + total_read, buf_size - total_read, file)) { total_read += strlen(buffer + total_read); if (total_read >= buf_size - 1) { buf_size *= 2; temp = realloc(buffer, buf_size); if (!temp) { perror("realloc failed"); free(buffer); fclose(file); return 1; } buffer = temp; } } if (total_read > 0) { printf("%s\n", buffer); } else { perror("No content read"); } free(buffer); fclose(file); return 0; }
关键要点
- 永远不要依赖
/proc下虚拟文件的st_size字段,这类文件的内容由内核动态生成,fstat()无法获取真实长度。 - 读取
/proc文件时,优先用足够大的静态缓冲区,或者通过动态扩容逐步读取直到文件结束。
内容的提问来源于stack exchange,提问作者Bret Joseph
相关产品推荐
相关产品推荐

