⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat16.cpp

📁 恢复误删除或误格式化且文件格式为FAT16格式的文件数据
💻 CPP
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>

 /******************************  BPB表  ***********************************/
	typedef struct{
		unsigned char z1[11];
		unsigned char b_ps[2];							//每扇区字节数
		unsigned char s_pc;									//每簇扇区数
		unsigned char s_b[2];								//保留扇区数
		unsigned char z2[6];
		unsigned char s_pf[2];							//每个FAT表的扇区数
		unsigned char z4[488];
	}bpb_table;

	/***************************  FAT表  *********************************/
	typedef struct{
		unsigned int fat[256];						//存放簇号
	}fat_table;


	/***************************   目录登记项   *************************/
	typedef struct{
		unsigned char f_n[8];							//文件名
		unsigned char f_en[3];						//文件扩展名
		unsigned char z1[15];
		unsigned char f_bc[2];							//起始簇号
		unsigned char f_l[4];							//文件长度
	}s_fdt;


	typedef struct{
	       s_fdt  fdt[16];								//16个登记项
		//char f_wn[32];
	}s_fidt;


	typedef struct{
	       s_fidt fidt[32];
	}fdt_table;										//FDT表
   /********************************************************************/
	void main(){
		unsigned int b_ps;									//每扇区字节数
		unsigned int s_pf;									//每FAT表的扇区数
		unsigned int s_b;									//保留扇区
		unsigned int f_bc;									//起始簇号
		char q[2]=".";
		//unsigned char ch[8192];							//CH大小为一个簇的大小
		unsigned char ch[1024];
		int i,j;
		unsigned int c;
		unsigned int count=0;
	//	long temp;
						//计算数据区簇号
		int k;
		int l;
		int b;												//标记
		unsigned long f_l;									//f_l存放文件长度
		char f_n[11];
		char f_en[5];
		FILE *fp;
		FILE *fp1;											//fp1新建恢复文件指针
		char sh[13];
		bpb_table bt1;
		fat_table fat1;
		fdt_table ft1;
		//char ch[512];

		printf("Please input the file name\n");
		scanf("%s",sh);
		if((fp=fopen(sh,"rb"))==NULL){
			printf("open errer!\n");
			exit(0);
		}




		fseek(fp,3072,0);
	
		fread(&bt1,1,512,fp);									//读BPB
		b_ps=(bt1.b_ps[1]<<8)|bt1.b_ps[0];						//每扇区字节数
		s_b=(bt1.s_b[1]<<8)|bt1.s_b[0];							//保留扇区数
		s_pf=(bt1.s_pf[1]<<8)|bt1.s_pf[0];						//每FAT扇区数
		long b_pc = bt1.s_pc*b_ps;								//b_pc:每簇字节数

		//char *ch;
		//long t = b_pc+1;
		//ch = (char *)malloc(t);
		printf("每扇区字节:%d\n",b_ps);
		printf("每簇扇区数:%d\n",bt1.s_pc);
		printf("保留扇区:%d\n",s_b);
		printf("每FAT表所占扇区数:%d\n",s_pf);
		getch();
//		fseek(fp,(s_b-1)*b_ps,1);						//跳过保留扇区
		fseek(fp,512,1);								//跳过保留扇区-1个扇区

		fseek(fp,2*s_pf*b_ps,1);								//跳过2个FAT,到达FDT
		
		for(i=0;i<32;i++)
			fread(&ft1.fidt[i],1,512,fp);					//读FDT表


		printf("input the file name that you want to resume: ");
		scanf("%s",f_n);
		printf("input the file extension:");
		scanf("%s",f_en);
		l=strlen(f_n);
		f_n[8]=f_en[0];
		f_n[9]=f_en[1];
		f_n[10]=f_en[2];
		
	
		for(i=0;i<32;i++)
		{														//每个FDT表占32扇区
			for(j=0;j<16;j++)
			{													//一个扇区,16个根目录
				b=0;
				if(l<=8){
					for(k=1;k<l;k++){
						if((f_n[k]!=ft1.fidt[i].fdt[j].f_n[k])&&((f_n[k]-32)!=\
							ft1.fidt[i].fdt[j].f_n[k])){
							b=1;
							break;
						}
					}
					for(k=0;k<3;k++){
						if((f_en[k]!=ft1.fidt[i].fdt[j].f_en[k])&&((f_en[k]-32)!=\
							ft1.fidt[i].fdt[j].f_en[k])){
						b=1;
						break;
						}
					}
					if(b==0){
						f_bc=(ft1.fidt[i].fdt[j].f_bc[1]<<8)|ft1.fidt[i].fdt[j].f_bc[0];					//f_bc起始簇
						//f_bc=ft1.fidt[i].fdt[j].f_bc[0];
						f_l=(ft1.fidt[i].fdt[j].f_l[3]<<24)|(ft1.fidt[i].fdt[j].f_l[2]<<16)|(ft1.fidt[i].fdt[j].f_l[1]<<8|ft1.fidt[i].fdt[j].f_l[0]);						//f_l文件长度
						//f_l=(ft1.fidt[i].fdt[j].f_l[1]<<8)|ft1.fidt[i].fdt[j].f_l[0];
						printf("The file found!\n");
						break;
					}
				}
			}
			if(b==0)  break;
		}
		if(b==1){	
			printf("Can not find the file!\n");
			exit(0);
		}
		
		unsigned temp;          //temp为文件最后一个簇所存储实际数据字节数
		
		if(f_l%b_pc!=0)	
		{//b_pc为没簇字节数
			c=(f_l/b_pc+1);		//c为文件占用簇的数目
			temp=f_l%b_pc;
		}					
		else c=f_l/b_pc;
		char rfn[20]="d:\\rf\\" ;					//存放的路径
		strcat(f_n,q);
		strcat(f_n,f_en);
		strcat(rfn,f_n);
		if((fp1=fopen(rfn,"wb+"))==NULL)
		{
			printf("Open file errer!");
			exit(0);
		}
		fseek(fp,(f_bc-2)*bt1.s_pc*b_ps,1);

		while(1)
		{	
			count++;												//count为 计算读了几个簇
			if(f_l%b_pc!=0)
			{
				if(count<c)
				{
					fread(&ch,bt1.s_pc*512,1,fp);
					fwrite(&ch,1,bt1.s_pc*512,fp1);						//写一个簇的内容
					//f_bc++;
				}
				
				else if(count==c)
				{
					fread(&ch,temp,1,fp);
					fwrite(&ch,1,temp,fp1);
					break;
				}
				
				else 
				{
					//f_bc++;
					count--;
				}

			}
			else
			{													//count为 计算读了几个簇
				if(count<=c)
				{
					fread(&ch,bt1.s_pc*512,1,fp);
					fwrite(&ch,1,bt1.s_pc*512,fp1);						//写一个簇的内容
					//f_bc++;
				}
				else 
				{
					//f_bc++;
					count--;
				}

				if(count==c)
					break;
			}
		}
		//rewind(fp);
		//rewind(fp1);
		if(fclose(fp)){
			printf("Close error!\n");
			exit(1);
		}
		if(fclose(fp1)){
			printf("Close error!\n");
			exit(1);
		}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -