📄 简单文件系统.cpp
字号:
/*对于本系统,分四个区域:系统引导区,FAT表区,根目录区和数据区。
主要数据结构:
1,FAT表:物理结构为整型数组,FAT[i]存放的是第i号盘块连接的下一个盘块号。
FAT表的值初始化为-1。FAT表亦充当位示图,当FAT[i]=-1表示该盘空闲。
2,FCB:文件控制块,为结构体类型,存放的数据有文件名,文件类型(目录文件或数据文件),文件建立时间
文件长度,文件起始盘块号。
3,当前文件打开表:为FCB类型数组,用于存放当前被打开的文件的FCB;
4,当前路径:为FCB类型数组,用于存放当前路径下从根目录到当前目录的所有文件的FCB
5,当前FCB指针:指示当前所处文件的FCB,为FCB类型指针
格式化磁盘过程:
1,将FAT表里的值全设置成-1
2,将根目录的FCB放到磁盘根目录区中
初始化过程:
1,将myfilesy文件到入到为其开辟的一虚拟磁盘空间中
2,读取虚拟磁盘空间中的FAT表到内存中,读取根目录的FCB到内存中,将其作为文件打开表数组的第一个元素
当前路径设置成root,当前FCB指针指向根目录的FCB
创建文件过程:
1,为所要创建的文件申请一个空白盘块
2,建立所要创建文件的FCB,将它放入到当前文件的数据区中
3,如果所创建文件为目录型文件,则令当前FCB指针指向新建立文件的FCB同时再当前文件打开表里加入新建立
的FCB,当前路径亦要更新*/
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>
#define file_size 1000000 //磁盘数据区大小
#define pan_size 1000 //盘块大小
#define steer_size 100 //引导区大小
#define fat_size 1000//FAT表数组大小
#define max_of 100//允许最多打开文件数的个数
#define max_cur 100//允许最长路径长度
#define fend 0//表示文件的最后一个盘块
#define blanked -1//表示盘块空闲
typedef struct FCB{
char fname[20];//文件名
int ftype;//文件类型
int fd;//盘块号
int fw;//盘块内已用空间偏移量
int flength;//文件大小
};
typedef struct CURRENT_CFLIST{
FCB *F;
int rw;
};//当前文件打开表
CURRENT_CFLIST current_cflist[max_cur];
int num_fcb = pan_size/sizeof(FCB);//一个盘块所能存放的FCB数量
int all_size = file_size+steer_size+2*fat_size;//磁盘总大小
char *pfile;//虚拟磁盘的起始地址
int *pfat; //虚拟磁盘中FAT表的起始地址
FCB *proot;//虚拟磁盘中根目录的起始地址
char *ptd;//虚拟磁盘中数据段的起始地址
int num_oflist=0;//当前文件打开个数
FCB current_dir[max_cur];//当前路径
int num_dir=0;//当前路径长度
//FCB *current_file;//当前文件FCB指针
FCB *current_cfile;//当前目录文件FCB指针
int Creatfilesy();//新建文件系统函数
int Format();//对文件存储器进行格式化函数
int Initsy(char*p);//对文件系统进行初始化
int Enterfilesy();//进入文件按系统函数
int Outfilesy();//推出文件系统函数
int Creat();//创建文件函数
int Mkdir();//创建子目录
int Rmdir();//删除空的子目录
int cd();//改变当前目录
int Open(char *fname);//打开文件函数
int Close(char *name);//关闭文件函数
int Wirte(char *name,char *buf,int count);// 文件写函数
int Read(char *name,char *buf,int count);//文件读函数
int Delete(char *name);//删除文件函数
int Recycle_pan(FCB *mf);//回收文件盘块
int Dir();//用于显示当前目录下的所有文件
int ls();//显示目录
int cd();//更改当前目录
int cfile();//显示当前被打开文件
int Enter_sy();
int Out_of_sy();
int Creatfilesy()
{
char *p = (char*)malloc(all_size*sizeof(char));
Format();
return 1;
}
int Format()
{
int all_size = file_size+steer_size+2*fat_size;
int i;
char rname[] = "root";
char *p = (char*)malloc(all_size*sizeof(char));
FILE *mf = fopen("myfilesy.txt","wb");//读文件时,一定要写成"rb",如果写成"wb",则文件原来的内容全被覆盖
pfat = (int *)(p+steer_size);
*pfat = fend;
for( i=0;i<2*fat_size;i++)
*(pfat+i) = blanked;
proot = (FCB*)(pfat+i);
proot->fd = 0;
proot->flength = 1;
strcpy(proot->fname,rname);
proot->ftype = 0;
proot->fw = 0;
//proot->opened = 1;
fwrite(p,sizeof(char),all_size,mf);
free(pfile);
pfile = p;
fclose(mf);
Initsy(pfile);
//free(p);
return 1;
}
int Initsy(char *p)
{
CURRENT_CFLIST TE;
pfat = (int*)(pfile+steer_size);
*pfat = fend;
proot = (FCB *)((int *)pfat+2*fat_size);
ptd = (char*)(proot+1);
num_dir = 0;
num_oflist = 0;
current_dir[num_dir++] = *proot;
TE.F = proot;
TE.rw = 0;//读写指针
current_cflist[num_oflist++] = TE;
current_cfile = proot;
ls();
return 1;
}
int ls()
{
printf("root:");
for(int i=1;i<num_dir;i++)
printf("%s\\",current_dir[i].fname);
return 1;
}
int cfile()
{
printf("\nThe file has opened now:\n");
for(int i=0;i<num_oflist;i++)
{
printf("file %d:\n",i);
printf("name: %s\n",current_cflist[i].F->fname);
if(current_cflist[i].F->ftype==0)
printf("type: content\n");
else
printf("type: data\n");
printf("first coil:%d\n",current_cflist[i].F->fd);
}
ls();
return 1;
}
int Dir()
{
int temp = current_cfile->fd;//当前目录文件的第一个盘块号
int n = 0;
while(*(pfat+temp)!=fend)
{
FCB *OR = (FCB*)(*(ptd+temp*pan_size));//找到盘块号的物理地址
for(int i=0;i<num_fcb;i++)
{
printf("File %d:\n",n++);
printf("name: %s\n",(OR+i)->fname);
if((OR+i)->ftype==0)
printf("type: content\n");
else
printf("type: data\n");
printf("first coil:%d\n",(OR+i)->fd);
}
}
FCB *OR = (FCB*)((ptd+temp*pan_size));//找到盘块号的物理地址
for(int i=0;i<((current_cfile->fw)/sizeof(FCB));i++)
{
printf("\nFile %d:\n",n++);
printf("name: %s\n",(OR+i)->fname);
if((OR+i)->ftype==0)
printf("type: content\n");
else
printf("type: data\n");
printf("first coil:%d\n",(OR+i)->fd);
}
if(n==0)
printf("\nThe is no file is current_content!\n");
ls();
return 1;
}
int Creat()
{
int i,j,f_d;
char name[20];
for(i=0;i<fat_size;i++)
if(*(pfat+i)==blanked)
break;
*(pfat+i) = fend;//将第i号盘块设置成已用
f_d = i;
int temp = current_cfile->fd;
while(*(pfat+temp)!=fend)
temp = *(pfat+temp);//找到文件的最后一个盘块
if(current_cfile->fw+sizeof(FCB)>pan_size)//当前文件存放不下新建文件的FCB
{
for(j=0;j<fat_size;j++)
if(*(pfat+j)==blanked)//寻找一空闲盘块
break;
*(pfat+temp)=j;//将该空闲盘块链接到文件原最后盘块之后以供使用
*(pfat+j)=fend;//将该空闲盘块设置成当前文件的最后一个盘块
current_cfile->fw = 0;//设置盘块内偏移量为0
current_cfile->flength++;//更新文件当前长度
temp = j;//令temp指向最后一个盘块
}
scanf("%s",name);
FCB *f = (FCB*)(ptd+(temp)*pan_size+current_cfile->fw);//计算存放新建FCB的物理位置
current_cfile->fw = current_cfile->fw + sizeof(FCB)/sizeof(char);//更新当前文件盘块内偏移量
for(i=0;i<num_oflist;i++)
if(strcmp(current_cfile->fname,current_cflist[i].F->fname)==0)
current_cflist[i].F = (current_cfile); //更新当前文件再当前打开文件表里的信息
f->fd = f_d;//填入新建文件FCB信息
f->flength = 1;
strcpy(f->fname,name);
f->ftype = 1;
f->fw = 0;
Open(f->fname);
return 1;
}
int Delete(char *name)
{
int i,flag;
Close(name);
int temp = current_cfile->fd;//当前目录文件的第一个盘块号
while(*(pfat+temp)!=fend)
{
FCB *OR = (FCB*)(*(ptd+temp*pan_size));//找到盘块号的物理地址
for(i=0;i<num_fcb;i++)
{
if(strcmp(name,(OR+i)->fname)==0)
{
Recycle_pan(OR+i);
for(int j=i+1;j<num_fcb;j++)
*(OR+j-1) = *(OR+j);
current_cfile->fw -= sizeof(FCB);
flag = 1;
break;
}
}
if(flag!=1)
temp = *(pfat+temp);//如果在当前盘块上没有找到待打开文件,则转到下一盘块去搜索
else
break;
}
if(flag!=1)
{
FCB *OR = (FCB*)((ptd+temp*pan_size));//找到盘块号的物理地址
for(i=0;i<num_fcb;i++)
{
if(strcmp(name,(OR+i)->fname)==0)
{
Recycle_pan(OR+i);
for(int j=i+1;j<num_fcb;j++)
*(OR+j-1) = *(OR+j);//覆盖待删除文件的FCB
current_cfile->fw -= sizeof(FCB);//更新父亲文件的盘块内偏移量
for(i=0;i<num_oflist;i++)
if(strcmp(current_cfile->fname,current_cflist[i].F->fname)==0)
current_cflist[i].F = (current_cfile); //更新当前文件再当前打开文件表里的信息
flag = 1;
break;
}
}
}
if(flag!=1)
printf("\nThe file has not exit!\n");
ls();
return 1;
}
int Recycle_pan(FCB *mf)//回收文件盘块
{
int temp = mf->fd;//到文件第一个盘块号
while(*(pfat+temp)!=fend)//再FAT表中查询盘块号信息,并回收盘块号
{
int k = *(pfat+temp);
*(pfat+temp) = blanked;
temp = k;
}
*(pfat+temp) = blanked;
return 1;
}
int Open(char *name)
{
// FCB *f,cf;
int i,flag;
int temp = current_cfile->fd;//当前目录文件的第一个盘块号
while(*(pfat+temp)!=fend)
{
FCB *OR = (FCB*)(*(ptd+temp*pan_size));//找到盘块号的物理地址
for(i=0;i<num_fcb;i++)
{
if(strcmp(name,(OR+i)->fname)==0)
{
current_cflist[num_oflist].F = (OR+i);
current_cflist[num_oflist++].rw = 0;
flag = 1;
break;
}
}
if(flag!=1)
temp = *(pfat+temp);//如果在当前盘块上没有找到待打开文件,则转到下一盘块去搜索
else
break;
}
if(flag!=1)
{
FCB *OR = (FCB*)((ptd+temp*pan_size));//找到盘块号的物理地址
for(i=0;i<num_fcb;i++)
{
if(strcmp(name,(OR+i)->fname)==0)
{
current_cflist[num_oflist].F = (OR+i);
current_cflist[num_oflist++].rw = 0;
flag = 1;
break;
}
}
}
if(flag!=1)
printf("\nThe file has not exit!\n");
ls();
return 1;
}
int Close(char *name)
{
int i,j;
for(i=0;i<num_oflist;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -