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

📄 简单文件系统.cpp

📁 本人在做操作系统课程设计时写的一个关于简单文件系统的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*对于本系统,分四个区域:系统引导区,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 + -