C从SD逻辑恢复图像

C从SD逻辑恢复图像,c,C,我正在尝试从SD卡FAT32恢复数据,因为我知道当我在那里找到.jpg时,它会一直在那里,直到文件结束。 现在,该程序能够恢复1个jpeg,但停止。我如何改进它,或者有人能指出我的逻辑缺陷吗 也在: 编辑:卡片文件 #包括 #包括 #包括 typedef uint8_t字节; #定义块大小512 内部主(空) { //定义512字节块 字节块[块大小]; //打开存储卡 FILE*fp=fopen(“card.raw”,“r”); //检查文件是否已打开 如果(fp==NULL) { print

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

也在:

编辑:卡片文件

#包括
#包括
#包括
typedef uint8_t字节;
#定义块大小512
内部主(空)
{
//定义512字节块
字节块[块大小];
//打开存储卡
FILE*fp=fopen(“card.raw”,“r”);
//检查文件是否已打开
如果(fp==NULL)
{
printf(“打开文件时出错”);
返回1;
}
//打开输出文件
文件*输出文件;
outfile=NULL;
int num=0;
字符文件名[14];
int x=0;
int y=1;
//主块直到文件结束
而(y==1)
{
如果(x==0)
{
//每512块读取一次
fread(&block,sizeof(block),1,fp);
}
//如果第4个字符是jpg
if((块[0]==0xff&&block[1]==0xd8&&block[2]==0xff&&block[3]==0xe0)| |(块[0]==0xff&&block[1]==0xd8&&block[2]==0xff&&block[3]==0xe1))
{
sprintf(文件名为“%03d_output.jpg”,num);
outfile=fopen(文件名,“a”);
fwrite(和block),sizeof(block),1,outfile;
//fseek(fp、sizeof(block)、SEEK_CUR);
fread(&block,sizeof(block),1,fp);
而(!((块[0]==0xff和块[1]==0xd8和块[2]==0xff和块[3]==0xe0)| |(块[0]==0xff和块[1]==0xd8和块[2]==0xff和块[3]==0xe1)))
{
fwrite(和block),sizeof(block),1,outfile;
y=fread(&block,sizeof(block),1,fp);
}
//fseek(fp,-(sizeof(block)),SEEK_CUR);
fclose(输出文件);
num++;
x=1;
//y=fread(&block,sizeof(block),1,fp);
}
//printf(“%s\n”,块);
}
//关闭存储卡
fclose(fp);
返回0;
}

一个问题是外环:

while (y == 512)
{
    ...lots of code...
    y = fread(&block, sizeof(block), 1, fp);
    ...some code...
}
fread()
y
设置为
0
1
,因此它不再是512,因此循环终止

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


这将从示例数据中提取文件000..050,并且
file
将其描述为以下三种类型之一:

  • JPEG图像数据,EXIF标准
  • JPEG图像数据,JFIF标准1.01
  • JPEG图像数据,JFIF标准1.02
工作代码
#包括
#包括
#包括
typedef uint8_t字节;
#定义块大小512
静态内联int是jpeg文件头(常量字节*块)
{
如果(块[0]==0xff和块[1]==0xd8和块[2]==0xff&&
(块[3]==0xe0 | |块[3]==0xe1))
返回1;
返回0;
}
内部主(空)
{
字节块[块大小];
常量字符文件[]=“card.raw”;
文件*fp=fopen(文件“r”);
如果(fp==NULL)
{
fprintf(stderr,“打开文件%s进行读取时出错,\n”,文件);
返回1;
}
int num=0;
while(fread(&block,sizeof(block),1,fp)==1)
{
如果(是jpeg文件头(块))
{
字符文件名[20];
snprintf(文件名,sizeof(文件名),“%03d_output.jpg”,num);
FILE*outfile=fopen(文件名,“a”);
如果(输出文件==0)
{
fprintf(stderr,“打开文件%s进行写入时出错,\n”,文件名);
返回1;
}
printf(“%s\n”,文件名);
fwrite(和block),sizeof(block),1,outfile;
而(fread(&block,sizeof(block),1,fp)==1&&
!is_jpeg_文件头(块))
{
fwrite(和block),sizeof(block),1,outfile;
}
fclose(输出文件);
num++;
fseek(fp,-块大小,SEEK_CUR);
}
}
fclose(fp);
返回0;
}
这使用了这样一个事实,即当您读取下一个文件的头时,我们正在读取磁盘映像以查找回一个块。这比继续编写代码更简单


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

FAT32不一定将文件的所有块存储在连续块中。您的程序需要读取并按照文件分配表(FAT)查找要恢复的每个文件的块。首先查找FAT32规范文档。或者只是寻找一个预先存在的恢复应用程序,而不是编写自己的恢复应用程序。这是一个练习,我每512字节就知道一些类似的东西,如果我找到一个.jpg,那么直到文件末尾都有.jpg。这是一个初学者的事情,但我不明白,而在第一次。jpg它不打印其他。(我知道有51.jpg需要恢复),在我能够找到所有51个字节之前,有一个无限的while循环,但是在输出文件中没有正确地生成它们,现在我可以正确地输出1,但是没有其他事情发生,你知道吗?我在某个地方读到fread(..)返回读取字节的值,在本例中是512,这就是为什么我放了(y==512)。我试图将其修改为while(y==1)。。。但是,它会正确地创建一个000.jpg文件,然后创建一个001.jpg1Gb+文件,并且永远不会停止循环。关于x yeah it's on Purpose函数的声明是:
size\t fread(void*restrict ptr、size\t size、size\t nitems、FILE*restrict stream)。第一个size参数是它正在计算的单位的大小;第二个是它正在计算的单位数。它将返回成功读取的单位数。如果将
1
作为第一个size参数,那么它确实会报告by的数量
while (y == 512)
{
    ...lots of code...
    y = fread(&block, sizeof(block), 1, fp);
    ...some code...
}
#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;
}