使用fmemopen创建的内存文件写入后无内容,求问题排查
问题:使用fmemopen合并文件后读取始终得到EOF
需求:读取磁盘多个文件合并,不想创建临时文件,用fmemopen在内存中通过FILE API操作,已有单个文件处理代码。核心代码如下(省略错误检查):
#define MODE_APPEND "a" int main(int argc, char *argv[]) { off_t concatenated_file_size = 0; for (int i = 1; i < argc; i++) { concatenated_file_size += get_file_size(argv[i]); } char *buf = nullptr; FILE *concatenated_file = fmemopen(buf, concatenated_file_size, MODE_APPEND); for (int i = 1; i < argc; i++) { FILE *file_to_concat = open_file(argv[i]); int c; while ((c = fgetc(file_to_concat)) != EOF) { fputc(c, concatenated_file); } } rewind(concatenated_file); int prevchar = fgetc(concatenated_file); }
其中get_file_size通过stat实现,open_file是带错误检查的fopen,均测试正常。但prevchar始终为EOF,写入内容未保存到fmemopen返回的FILE*中,请问是API特性还是代码有误?
原因与修正方案
你的代码存在两处关键错误,并非fmemopen的API特性问题:
1. 空指针buf与追加模式的冲突
当buf传入nullptr时,fmemopen会自动分配一块大小为concatenated_file_size的内存,但你使用的"a"(追加模式)会让文件指针初始指向内存块的末尾。此时写入内容会直接超出内存块的有效范围,触发未定义行为,实际没有任何内容被写入到有效内存区域,后续自然读取到EOF。
2. 追加模式的使用场景错误
"a"模式设计用于磁盘文件的追加写入,但fmemopen的内存块是固定大小的。你计算的总大小刚好是内存块的容量,初始指针在末尾后,没有剩余空间容纳写入的内容,直接导致写入失败(或越界)。
修正后的核心代码
#define MODE_RW "w+" // 改用读写模式,初始指针指向内存块开头,支持读写操作 int main(int argc, char *argv[]) { off_t concatenated_file_size = 0; for (int i = 1; i < argc; i++) { concatenated_file_size += get_file_size(argv[i]); } // 手动分配内存,方便后续直接访问合并后的内容(也可传NULL让fmemopen自动分配) char *buf = malloc(concatenated_file_size); if (!buf) { // 此处添加错误处理逻辑 } FILE *concatenated_file = fmemopen(buf, concatenated_file_size, MODE_RW); for (int i = 1; i < argc; i++) { FILE *file_to_concat = open_file(argv[i]); int c; while ((c = fgetc(file_to_concat)) != EOF) { fputc(c, concatenated_file); } fclose(file_to_concat); // 关闭文件避免资源泄漏 } rewind(concatenated_file); int prevchar = fgetc(concatenated_file); // 此时可正确读取第一个字符 // 后续处理合并后的内容... fclose(concatenated_file); free(buf); // 释放手动分配的内存 }
额外注意事项
- 如果让fmemopen自动分配内存(buf传NULL),后续无法直接通过buf访问内容,需借助
fread等API读取;手动分配内存则可直接操作buf指针 - 所有打开的FILE*必须调用
fclose关闭,防止文件描述符泄漏 - 写入完成后,除了
rewind,也可以用fseek(concatenated_file, 0, SEEK_SET)将指针移到开头进行读取
内容的提问来源于stack exchange,提问作者Nate
相关产品推荐
相关产品推荐

