You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键改动说明

  1. 语义更清晰的标记变量:把found_jpeg改成writing_jpeg,明确用来标记当前是否处于写入JPEG文件的状态,避免逻辑混淆。
  2. 正确的文件切换时机:只有在检测到新的JPEG头时,才会关闭之前的文件(如果有的话)并创建新文件,其余时候要么继续写入当前文件,要么跳过无效数据。
  3. 补全必要头文件:添加了stdint.h和stdbool.h,避免编译时出现类型未定义的错误。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:59:50