C语言从RAW数据恢复JPEG时生成过多文件的问题求助
C语言从RAW数据恢复JPEG时生成过多文件的问题求助
看起来你遇到的核心问题是代码的文件切换逻辑出错了——现在你的程序只要检测到第一个JPEG头之后,每个512字节的块都会生成一个新文件,这就是为什么会产出900多个JPG的原因。我们来一步步拆解问题并修正:
问题根源分析
你的代码里,一旦found_jpeg变为true,后续每一次循环都会执行fclose(outptr)然后重新打开一个新文件,这完全违背了需求逻辑:我们只应该在发现新的JPEG头的时候才切换文件,其余时候应该持续往当前打开的文件里写入数据。此外,found_jpeg的语义也不够清晰,导致你误用它触发了不必要的文件创建操作。
修正后的代码
#define CHUNK_SIZE 512 #include <stdio.h> #include <stdint.h> #include <stdbool.h> int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: ./recover FILE\n"); return 1; } char *file = argv[1]; FILE *card = fopen(file, "r"); if (card == NULL) { printf("File could not be opened\n"); return 2; } uint8_t buffer[CHUNK_SIZE]; int jpeg_count = 0; char jpeg_name[8]; FILE *outptr = NULL; bool writing_jpeg = false; // 改为标记当前是否正在写入JPEG文件 while (fread(buffer, 1, CHUNK_SIZE, card) == CHUNK_SIZE) { // 先判断当前块是否是新的JPEG头 bool is_new_jpeg = (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0); if (is_new_jpeg) { // 如果正在写之前的JPEG文件,先关闭它 if (writing_jpeg) { fclose(outptr); } // 创建新的JPEG文件并写入当前块 sprintf(jpeg_name, "%03i.jpg", jpeg_count); outptr = fopen(jpeg_name, "w"); fwrite(buffer, 1, CHUNK_SIZE, outptr); jpeg_count++; writing_jpeg = true; // 更新标记:现在正在写入JPEG } else if (writing_jpeg) { // 不是新头,但正在写入JPEG,就继续往当前文件写数据 fwrite(buffer, 1, CHUNK_SIZE, outptr); } // 既不是新头也没在写JPEG的情况,直接跳过(属于JPEG之前的无效数据) } // 循环结束后关闭最后一个打开的JPEG文件(如果存在) if (writing_jpeg) { fclose(outptr); } fclose(card); return 0; }
关键改动说明
- 语义更清晰的标记变量:把
found_jpeg改成writing_jpeg,明确用来标记当前是否处于写入JPEG文件的状态,避免逻辑混淆。 - 正确的文件切换时机:只有在检测到新的JPEG头时,才会关闭之前的文件(如果有的话)并创建新文件,其余时候要么继续写入当前文件,要么跳过无效数据。
- 补全必要头文件:添加了
stdint.h和stdbool.h,避免编译时出现类型未定义的错误。
内容来源于stack exchange
相关产品推荐
相关产品推荐

