计算机科学与技术学院2018-2019学年第一学期《操作系统》实验报告班级:XXXXXXX学号:XXXXXXXXX姓名:XXX教师:XXX成绩:1.题目分析1.1设计目的深入了解磁盘文件系统的实现。1.2设计内容(1)设计一个简单的文件系统,用文件模拟磁盘,用数组模拟缓冲区,要求实现:(2)支持多级目录结构,支持文件的绝对读路径;(3)文件的逻辑结构采用流式结构,物理结构采用链接结构中的显示链接方式;(4)采用文件分配表;(5)实现的命令包括建立目录、列目录、删除空目录、建立文件、删除文件、显示文件内容、打开文件、读文件、写文件(追加方式)、关闭文件、改变文件属性。(6)最后编写主函数对所做工作进行测试。1.3相关知识概述(1)文件的操作:①创建文件;②删除文件;③读文件;④写文件;⑤设置文件读/写位置。(2)文件的逻辑结构:从用户的观点出发所能观察到的文件组织形式,即问价是由一系列的逻辑记录组成的,是用户可以直接处理的数据及其结构。文件的物理结构:系统将文件存储在外存上所形成的一种存储组织形式,用户不可见。(3)磁盘空间的管理:采取合理的文件分配方式,为每个文件分配必要的存储空间,使每个文件都能“各得其所”,并能有效减少磁盘碎片。(4)磁盘目录结构2.实验设计2.1基本设计思路用一个文件模拟磁盘:0123456789101112FAT根目录目录1目录2目录3目录4…文件1文件2…文件分配表FAT(128B):第几项0123456789…内容-1-1-149078-112…根目录(64B)目录1(64B)目录6(64B)目录n……….实验中,模拟的磁盘有128块,每块64B,故文件分配表有128项,每项3一个字节,共占磁盘的前两块,盘块编号0、1;根目录紧邻在文件分配表后面,占编号为2的盘块。8B8B8B8B8B8B8B8B文件管理系统要实现的功能包括:(1)磁盘操作:①磁盘分配(2)目录操作:①建立目录②显示目录内容③删除空目录(3)文件操作:①建立文件②打开文件③关闭文件④读文件⑤写文件⑥删除文件(磁盘回收)⑦显示文件内容⑧改变文件属性⑨使用绝对路径名查找文件(4)对数据结构——已打开文件表的操作:①在已打开文件表中查找某文件②将文件从已打开文件表中删除③将某文件插入已打开文件表2.2主要数据结构描述1、每个目录项的数据结构(8B):typedefstruct{charname[3];//文件/目录名chartype[2];//文件类型目录未使用字节(填充空格)intattribute;//属性intstartnum;//起始盘块号intlength;//文件长度目录未使用字节(填充0)}DF_item;2、已打开文件表项类型:typedefstruct{charname[20];//文件绝对路径名charattribute;//文件的属性,用1个字节表示,所以采用char类型intnumber;//文件起始盘块号intlength;//文件长度,文件占用的字节数intflag;//操作类型,用“0”表示以读操作方式开文件,用“1”表示写操作方式打开文件pointerread;//读文件的位置,文件打开时dnum为文件起始盘块号,bnum为“0”pointerwrite;//写文件的位置,文件刚建立时dnum为文件起始盘块号,bnum为“0”,打开文件时dnum和bnum为文件的末尾位置}OFILE;3、已打开文件登记表:struct{OFILEfile[n];//已打开文件登记表intlength;//已打开文件登记表中登记的文件数量}openfile;2.3主要算法描述(1)磁盘分配:(2)对已打开文件表的操作:①在已打开文件表中查找某文件:开始找到文件分配表第x项,i=x第i项值是否为0?第i项是否为最后一项?磁盘满,分配失败结束i=i+1分配第i块NYNY图2-10分配一个磁盘块的流程图②将某文件从已打开文件表中删除结束查找路径名为pname的文件i=0i为已打开文件表一栏?查找成功结束查找失败i=i+1文件路径名相符?NNYY开始删除路径名为name的文件在已打开文件表中查找路径名为name的登记项i找到该文件登记项?删除第i项:openfile.file[i]=openfile[openfile.length-1]openfile.length=openfile.length-1结束文件没有打开,删除失败NY图2-13在已打开文件表中查找某文件图2-14将某文件从已打开文件表中删除的流程图③将某文件插入已打开文件表(3)目录操作:①建立目录结束插入路径名为name的文件在已打开文件表中查找路径名为name的登记项找到该文件登记项?已打开文件表已满?文件登记表满,无法打开文件结束在openfile.file[length]处填写该文件的各项内容:openfile.length=openfile.length+1文件已打开YNYN图2-15将某文件插入已打开文件表的流程图②显示目录内容③删除空目录删除空目录首先要找到该目录,如果目录不存在,指令执行失败;如果存在,但是根目录或非空目录,显示不能删除,操作失败;若是非空子目录,则删除其目录项并回收对应空间。删除空目录的过程和删除文件的过程相似,流程可参考文件的删除过程。开始显示路径名为name的目录查找目录name找到该目录?该目录项起始盘块号dnum;第dnum块内容读入buffer2指定目录不存在,显示目录内容失败结束t=0查buffer2中第t个目录项第t项是空目录项?显示该目录内容第t项是该盘块最后一项?结束t=t+1NYNYYN图2-24显示目录内容的流程图(4)文件操作:①建立文件②打开文件③关闭文件结束打开路径名为pname的文件查找文件的目录项找到该文件目录项?文件属性与操作类型相符?在已打开文件表中插入该文件登记项结束文件不存在,无法打开文件操作不合法无法打开文件NYYN图2-17打开文件的流程图④读文件开始关闭文件路径名为name的文件查找已打开文件表文件打开?追加文件结束符修改目录中文件长度结束文件未打开,无法关闭文件结束在已打开文件表中删除该文件登记项操作为“写”?NNYY图2-20模拟关闭文件的流程图⑤写文件开始读name文件length字节查找已打开文件表文件打开?文件以读方式打开?从已打开文件表的到读指针:将盘块dum读入缓冲buffer1文件未打开,无法读文件结束文件不能读结束t=0文件未结束且t=length显示读出内容;修改读指针的bunum:bnum=bnum+1t=t+1读完一个盘块?修改读指针bnum=0;:dnum=文件分配表第num项将盘块dnum读入缓冲buffer1读文件结束结束NYNNNYYY⑥删除文件(磁盘回收)⑦显示文件内容⑧改变文件属性改变文件属性,首先查找该文件,如果不存在,结束;如果存在,检査文件是否打开,打开不能改变属性;没有打开,根据要求改变目录项中属性值。⑨使用绝对路径名查找文件结束显示路径名为name的文件查找目录name找到该文件?文件打开?dnum=该目录起始盘块号第dnum块是该文件一块?第dnum块内容读入buffer1显示buffer1中的内容结束或到文件结束符dnum=FAT第dnum项结束结束文件打开,显示文件失败结束指定的文件不存在,显示文件内容失败NYNYNY3.编码实现3.1实现过程总结部分功能代码:(1)目录操作:①建立目录:intmd(char*pathName,char*contentName,charaddress)//建立目录{intdnum;intbnum;intcbnum;intsize=strlen(contentName);boolresult=search_by_rname(pathName,0,&dnum,&bnum,&cbnum);if(result==false){return0;//返回值为0代表绝对路径输入有误,重新建立}contentcn;inti=0;for(i=0;i3;i++){cn.name[i]=255;}for(i=0;isize;i++)//为新建的name字段进行赋值{cn.name[i]=contentName[i];}cn.name[i]='\0';cn.type[0]='';cn.type[1]='';cn.attribute=8;cn.address=address;cn.length='';intresult1=search(dnum);if(result1==-1){return2;//表示所选的父目录中没有空间}if(!isBlockEmpty(address)){return3;}fseek(fc,address,SEEK_SET);unsignedcharc1=getc(fc);if(c1==254){return4;}fseek(fc,dnum*64+result1,SEEK_SET);contentc[1];c[0]=cn;fwrite(c,8L,1,fc);fseek(fc,(int)address,SEEK_SET);putc(255,fc);for(inti=0;i8;i++){contentBuffer[i].name[0]='$';}fseek(fc,address*64,SEEK_SET);fwrite(contentBuffer,64L,1,fc);return1;///1代表创建目录}②显示目录内容:intdir(char*pathName){intdnum;intbnum;intcbnum;boolresult=search_by_rname(pathName,0,&dnum,&bnum,&cbnum);if(result==false){return0;//路径查找失败}fseek(fc,dnum*64,SEEK_SET);fread(contentBuffer,64L,1,fc);for(inti=0;i8;i++){cout第i+1项的内容是:endl;if(contentBuffer[i].attribute==8)//这是一个目录{cout名字:contentBuffer[i].nameendl;cout类型:空endl;cout属性:目录项endl;cout起始地址:(int)contentBuffer[i].addressendl;cout长度:1endlendl;}elseif(contentBuffer[i].name[0]=='$'){cout一个空的目录登记项endl;}else{cout名字:contentBuffer[i].nameendl;cout类型:contentBuffer[i].typeendl;if(contentBuffer[i].attribute==3){cout属性:只读系统文件endl;}else{cout属性:可读可写的普通文件endl;}cout起始地址:(int)contentBuffer[i].addressendl;cout长度(int)contentBuffer[i].lengthendlendl;}}}(2)文件操作:①建立文件:boolcreate_file(){//让用户输入文件所在的绝对路径charabsolutePath[20];getchar();cout请输入文件所在的绝对路径:;gets_s(absolutePath,20);//检查目录是否存在intdnum;//该目录所在的磁盘盘块号inta;if(!search_by_rname(absolutePath,1,&dnum,&a,&a)){cout路径不存在!endl;returnfalse;}//检查该目录中是否有空余的登记项的位置intbnum=search1(dnum);if(b