实验题目文件管理一.实验目的本实验模拟操作系统中的建立文件、删除文件、建立目录、显示目录、改变目录和删除目录等操作。通过该实验使学生了解文件系统的基本结构和文件的各种管理方法。二.实验原理文件通常存放在外存(如磁盘、磁带)上,可以作为一个独立单位存放和实施相应的操作(如打开、关闭、读、写等)。为了加快对文件的检索,往往将文件控制块集中在一起进行管理。这种文件控制块的有序集合称为文件目录。文件控制块就是其中的目录项。图6-1示例一种目录的组织形式。三.实验内容模拟一个文件系统,包括目录文件,普通文件,并实现对它们的一些基本操作。假定每个目录文件最多只能占用一个块;一个目录项包括文件名(下一级目录名),文件类型,文件长度,指向文件内容(下一级目录)的指针内容。普通文件可以只用目录项(FCB)代表。四.实验环境软件环境:VisualC++6.0五.试验步骤源程序#includestdio.h#includestdlib.h#includeconio.h#includestring.h//头文件#defineN10inti,j;charh[100][100]={0};//用一个100*100的数组来模拟磁盘typedefstructtree{charname[3];/*文件或目录名*/chartype[2];/*文件类型名*/charattribute;/*属性*///0表示文件,1表示目录.charaddress;/*文件或目录的起始盘块号*/charlength;/*文件长度,以盘块为单位*/structtree*l,*r;/*文件或目录的链式结构*/}content;/*目录结构*/typedefstruct{intdnum;/*磁盘盘块号*/intbnum;/*盘块内第几项*/}pointer;/*已打开文件表中读写指针的结构*/typedefstruct{charname[20];/*文件绝对路径名*/charattribute;/*文件的属性,用1个字节表示,所以用了char类型*/intnumber;/*文件起始盘块号*/intlength;/*文件长度,文件占用的字节数*/intflag;/*操作类型,用0表示以读操作方式开文件,用1表示写操作方式打开文件*/pointerread;/*读文件的位置,文件刚打开时dnum为文件起始盘块号,bnum为0*/pointerwrite;/*写文件的位置,文件建立时dnum为文件起始盘块号,bnum为0,打开时为文件末尾*/}OFILE;/*已打开文件表项类型定义*/struct{OFILEfile[N];/*已打开文件表*/intlength;/*已打开文件表中登记的文件数量*/}openfile;/*已打开文件表定义*/charbuffer1[64];/*模拟缓冲1*///模拟磁盘上的物理块中存放的具体数据contentbuffer2[8];/*模拟缓冲2*///模拟磁盘上的物理块中存放的目录FILE*fc;/*模拟磁盘的文件指针*/sopen(char*name)//在已打开文件表中查找文件name{}dopen(char*name)//在已打开文件表中删除文件name{}iopen(content*x)//在已打开文件表openfile数组中插入文件name{}intallocate()//分配一个磁盘块,返回块号。从FAT中依次查找,找到一个空闲的磁盘区,返回它的编号{for(i=0;i100;i++)if(h[i][99]==0){h[i][99]=1;returni;//返回数组号,即为盘块号break;}}intsearch(content*p,contentfile)//查找路径名为name的文件或目录,返回该目录的起始盘块号,P是指向当前目录的指针{content*q,*q1;//P是指向当前目录的指针,不能轻易改变,引入q来代替pq=p;if(q-l-name[0]==file.name[0]&&q-l-name[1]==file.name[1]&&q-l-name[2]==file.name[2])//判断文件名与当前目录中的相同名{returnq-l-address;//若找到则返回此文件的磁块号}else//由于目录管理的数据结构为二叉树,所以需要对二叉树进行遍历{q=q-l;while(q-r!=0)//对根目录的左子树的右子树进行遍历,即为树中父结点的孩子结点{if(q-r-name[0]==file.name[0]&&q-r-name[1]==file.name[1]&&q-r-name[2]==file.name[2]){returnq-r-address;break;}//返回文件的磁块号elseq=q-r;//否则指针指向下一结点,继续遍历}}}create_file(content*&p)//建立文件{contentfile,*q,*q1;q=p;if(q-l==0){q-l=q1=(content*)malloc(sizeof(content));q-l-l=q-l-r=0;}else//判断当前位置以及建立文件的目录{q=q-l;while(q-r!=0)q=q-r;q-r=q1=(content*)malloc(sizeof(content));//向内存申请新的空间作为结点q-r-l=q-r-r=0;//新结点的初使化}printf(Pleaseinputthenameoffile(3letters):\n);//输入文件名scanf(%s,q1-name);printf(Pleaseinputthetypeofthefile(2letters):\n);//输入文件类型scanf(%s,q1-type);q1-address=allocate();//文件起始盘块号q1-attribute=0;printf(Pleaseinputthecontentofthefile(lessthan100letters):\n);//输入文件内容scanf(%s,h[q1-address]);//并将文件内容存放到磁块中printf(建立文件成功!\n);}open_file(content*&p)//打开文件{intb;contentfile;printf(Pleaseinputthenameoffile(3letters):\n);//输入要查找的文件名scanf(%s,file.name);printf(%s\n,h[search(p,file)]);//输出文件内容这里调用了自定义search()函数printf(打开文件成功!\n);}close_file(char*name){}Delete(content*&p)//文件或目录的删除{content*q,*q1,*q2;charstr[3];q=q1=p;printf(Pleaseinputthenameoffile(3letters):\n);//输入文件名scanf(%s,str);if(p!=0){//P是指向当前目录的指针,不能轻易改变,引入q来代替pif(q-l!=0){if(q-l-name[0]==str[0]&&q-l-name[1]==str[1]&&q-l-name[2]==str[2])//判断文件名与当前目录中的相同名{q2=p-l;//释放时用q2来释放p-l=p-l-r;//删除文件或目录,即将其从链表中除去free(q2);printf(删除成功!\n);}else//由于目录管理的数据结构为二叉树,所以需要对二叉树进行遍历{q=q-l;while(q-r!=0)if(q-r-name[0]==str[0]&&q-r-name[1]==str[1]&&q-r-name[2]==str[2]){q2=q-r;//释放时用q2来释放if(q-r-r!=0)q-r=q-r-r;//删除文件或目录,即将其从链表中除去elseq-r=0;//!!!!!!!!!!!!注意!!!!!!!链表的删除!!!free(q2);printf(删除成功!\n);break;}elseq=q-r;}}}elseprintf(NOfolders!\n);return0;}md(content*&p)//新建目录函数{contentfile,*q,*q1;q=p;if(q-l==0){q-l=q1=(content*)malloc(sizeof(content));q-l-l=q-l-r=0;}else//判断当前位置以及建立文件的目录{q=q-l;while(q-r!=0)q=q-r;q-r=q1=(content*)malloc(sizeof(content));//向内存申请新的空间作为结点q-r-l=q-r-r=0;}printf(Pleaseinputthenameoffile(3letters):\n);//输入文件名scanf(%s,q1-name);q1-attribute=1;//用1表示新建的为目录属性printf(新建目录成功!\n);return0;}cd(content*&p)//进入下一级子目录函数{content*q,*q1;charstr[3];q=q1=p;printf(Pleaseinputthenameoffile(3letters):\n);//输入文件名scanf(%s,str);if(p!=0){//P是指向当前目录的指针,不能轻易改变,引入q来代替pif(q-l!=0){if(q-l-name[0]==str[0]&&q-l-name[1]==str[1]&&q-l-name[2]==str[2])//判断文件名与当前目录中的相同名{p=p-l;}else//由于目录管理的数据结构为二叉树,所以需要对二叉树进行遍历{q=q-l;while(q-r!=0)if(q-r-name[0]==str[0]&&q-r-name[1]==str[1]&&q-r-name[2]==str[2]){q=q-r;p=q;break;}elseq=q-r;}}}elseprintf(NOfolders!);return0;}dir(content*&p)//显示目录及文件{content*q,*q1;q=p;if(q-l!=0){printf(%s,q-l-name);if(q-l-attribute==1)printf(DIR\n);//判断是文件还是目录elseprintf(FILE\n);q=q-l;//指针指向下一结点while(q-r!=0){printf(%s,q-r-name);if(q-r-attribute==1)printf(DIR\n);//判断是文件还是目录elseprintf(FILE\n);q=q-r;}}elseprintf(NOfolders!\n);//不存在文件或目录显示nofolders!return0;}content*cd_(content*&p,content*head)//返回顶级目录,主目录!!注意此函数为递归,注意参数的使用{content*q;q=head;if(q-l==p){p=q;returnp;}elseif(q-r=p){p=q;returnp;}if(q){cd_(p,q-l);//左孩子的递归cd_(p,q-r);//右孩子的递归}//return0;}print()//显示界面函数{printf(\n**********************************\n);printf(1:建立文件\n);printf(2:打开文件\n);printf(3:删除文件或目录\n);printf(4:建立目录\n);print