C语言实现内存卡JPG恢复出现file format not supported错误
代码问题修复说明
你的代码存在4个核心逻辑问题,逐一修正后即可正常恢复JPG文件:
- 文件打开模式错误:内存卡镜像和JPG都是二进制文件,你当前使用文本模式
"r"读镜像、"w"写JPG,在Windows环境下会自动对换行符做转义处理,直接破坏二进制数据结构。需要将打开模式改为二进制模式:读用"rb",写用"wb"。 - 重复读数据丢了JPG头:循环开头已经通过
fread读取了一个512字节块到buffer中,当检测到这个块是JPG头时,你额外调用了一次fread覆盖了当前的头块,相当于每个JPG的文件头被直接跳过,写入的第一个块是头块之后的内容,缺失头的JPG自然无法识别。需要删掉检测到JPG头后的额外fread调用,直接写入当前已经读取到的buffer即可。 - 未关闭最后一个JPG文件:只有检测到新JPG头时才会关闭上一个JPG文件,循环结束后最后一个写入的JPG文件没有执行
fclose,操作系统的文件缓冲区数据没有刷入磁盘,导致最后一个文件(甚至所有文件)不完整。需要在循环结束后补充fclose(image)逻辑,同时也要记得关闭原始镜像文件。 - 参数写法不规范(不影响运行):
is_jpg函数的参数BYTE(buffer[])写法冗余,可改为标准写法BYTE buffer[]。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <stdint.h> typedef uint8_t BYTE; int is_jpg(BYTE buffer[]) { if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xe0) == 0xe0) { return 1; } else { return 0; } } int main(int argc, char *argv[]) { BYTE buffer[512]; // 校验参数合法性 if (argc != 2) { printf("Usage: ./recover image\n"); return 1; } // 二进制模式打开镜像文件 FILE *file = fopen(argv[1], "rb"); if (file == NULL) { printf("No file found\n"); return 2; } int file_count = 0; char file_name[8]; FILE *image = NULL; while (fread(buffer, 512, 1, file) == 1) { if (is_jpg(buffer) == 1) { // 关闭上一个正在写入的JPG文件 if (image != NULL) { fclose(image); } // 创建新JPG文件 sprintf(file_name, "%03d.jpg", file_count); image = fopen(file_name, "wb"); file_count++; } // 只要已经找到第一个JPG,就写入当前块 if (image != NULL) { fwrite(buffer, 512, 1, image); } } // 关闭最后一个JPG文件和原始镜像文件 if (image != NULL) { fclose(image); } fclose(file); return 0; }
内容的提问来源于stack exchange,提问作者yonatan goldin
相关产品推荐
相关产品推荐

