📄 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 + -