0

我正在尝试从 SD 卡 FAT32 中恢复数据,因为我知道当我在.jpg那里找到它时,它会按顺序在那里直到文件结束。现在该程序能够恢复 1 jpeg 但停止。我该如何改进它,或者有人可以指出我的逻辑缺陷吗?

也在: http: //pastebin.com/Rak6L5Z0

编辑:卡片文件 http://www.mediafire.com/?et8pvhvacpy9kv1

 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>

 typedef uint8_t BYTE;

 #define BLOCKSIZE 512

 int main(void)
 {
    // define 512 byte block
    BYTE block[BLOCKSIZE];

    // open memory card
    FILE* fp = fopen("card.raw", "r");

    // check if file opened
    if (fp == NULL)
    {
        printf("Error opening file\n");
        return 1;
    }
    // open output file
    FILE* outfile;
    outfile = NULL;
    int num = 0;
    char filename[14];
    int x = 0;
    int y = 1;

    // main block till end of file
    while (y == 1)
    {
        if ( x == 0)
        {
        // read every 512 block
        fread(&block, sizeof(block), 1 , fp);
        }

        // if 4 first characters jpg
        if ((block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && block[3] == 0xe0) || (block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && block[3] == 0xe1))
        {
            sprintf(filename, "%03d_output.jpg", num);
            outfile = fopen(filename, "a");
            fwrite(&block, sizeof(block), 1, outfile);
            //fseek(fp, sizeof(block), SEEK_CUR);

            fread(&block, sizeof(block), 1 , fp);
            while (!((block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && block[3] == 0xe0) || (block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && block[3] == 0xe1)))
            {
                fwrite(&block, sizeof(block), 1, outfile);
                y = fread(&block, sizeof(block), 1, fp);
            }
            //fseek(fp, -(sizeof(block)), SEEK_CUR);
            fclose(outfile);
            num++;
            x = 1;
            //y = fread(&block, sizeof(block), 1, fp);
        }
        //printf("%s\n", block);

    }

    // close memory card
    fclose(fp);

    return 0;
 }
4

1 回答 1

1

一个问题是外循环:

while (y == 512)
{
    ...lots of code...
    y = fread(&block, sizeof(block), 1, fp);
    ...some code...
}

fread()设置y0or ,因此1不再是 512,因此循环终止。

if (x == 0)我认为后面的也有问题x = 1;,但我不确定我是否理解这部分代码背后的逻辑。当然,x在读取第一个文件后不会重置为零 - 如果这很重要。


这将从样本数据中提取文件 000..050,并将file它们全部描述为以下三种类型之一:

  • JPEG图像数据,EXIF标准
  • JPEG 图像数据,JFIF 标准 1.01
  • JPEG 图像数据,JFIF 标准 1.02

工作代码

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t BYTE;

#define BLOCKSIZE 512

static inline int is_jpeg_file_header(const BYTE *block)
{
    if (block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff &&
            (block[3] == 0xe0 || block[3] == 0xe1))
        return 1;
    return 0;
}

int main(void)
{
    BYTE block[BLOCKSIZE];
    const char file[] = "card.raw";

    FILE* fp = fopen(file, "r");
    if (fp == NULL)
    {
        fprintf(stderr, "Error opening file %s for reading\n", file);
        return 1;
    }

    int num = 0;

    while (fread(&block, sizeof(block), 1, fp) == 1)
    {
        if (is_jpeg_file_header(block))
        {
            char filename[20];
            snprintf(filename, sizeof(filename), "%03d_output.jpg", num);
            FILE* outfile = fopen(filename, "a");
            if (outfile == 0)
            {
                fprintf(stderr, "Error opening file %s for writing\n", filename);
                return 1;
            }
            printf("%s\n", filename);

            fwrite(&block, sizeof(block), 1, outfile);
            while (fread(&block, sizeof(block), 1 , fp) == 1 &&
                    !is_jpeg_file_header(block))
            {
                fwrite(&block, sizeof(block), 1, outfile);
            }
            fclose(outfile);
            num++;
            fseek(fp, -BLOCKSIZE, SEEK_CUR);
        }
    }

    fclose(fp);

    return 0;
}

这使用了我们正在读取磁盘映像的事实,以便在您读取下一个文件的标题时回溯一个块。它比继续代码更简单。

前 11 个恢复的图像都可以在 Web 浏览器中显示。

于 2013-09-18T05:34:39.207 回答