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