一、试验目的理解操作系统文件系统设计的原理二、试验要求1、模拟实现一个1M大小的文件系统,其中512B为一个扇区2、要求实现打开文件,关闭文件,创建文件,创建目录,删除文件,删除目录,显示目录下的文件等操作。3、实验平台不限,linux和windows均可。三、试验环境WindowsXP,vc++6.0四、试验内容本次实验内容是文件系统,因为windows多用图形用户界面操作,对其具体的文件系统不了解,所以本次实验模仿了linux下的文件指令。首先强调一点,linux的所有文件和目录都在根目录——/下程序实现的顶层操作列表如下:1目录指令指令作用mkdirname创建名为name的目录,可以包含路径cdname进入名为name的目录,可以包含路径如果name=..为返回上一级目录ls列出当前目录下的所有文件和目录ll列出当前目录下的所有文件和目录,并显示具体信息pwd显示当前目录的路径rmname删除当前目录下的目录及其子目录和目录下的所有文件,不支持绝对路径2文件指令指令作用touchname在当前目录下建立名为name的文件,支持列出绝对路径catname显示目录下名为name的文件内容,支持绝对路径viname编辑名为name的文件,这里是模仿linux下vi编辑器,但是本程序只能编辑已经存在的文件编辑后,输入q退出(相当于关闭文件)dname删除当前目录下名为name的文件,不支持绝对路径3系统指令指令作用treefolder_name列出指定目录的树形图exit退出文件系统date显示当前时间日期h显示帮助文档df查看磁盘剩余空间对于底层的功能,程序中表示磁盘的数据结构为一数组名为inf的数组为一个信息表,其中包含了该空间是否可用以及下个单元的位置这里要说明一下,此模拟的磁盘是仿照链式存储做的,每一块都记录下一条内容的位置的信息结构如图:代码太长,还是看一个运行的例子吧构建一个如下所示的文件系统要输入的指令如下:mkdiramkdirbtouchacdatouchbmkdirccd..cdbmkdirdcddmkdiremkdirftouchccd/tree/运行结果:接下来是编辑三个文件a、b、c的内容在这里我们可以先查看一下文件夹和文件的大小:用ll指令我们可用看到目前所有的文件和文件夹大小都为0接下来我们给图中的三个文件输入内容从上图看到,当再次输入ll指令时,文件和文件夹大小均改变,且文件的改动时间也更新了接下来我们试一下删除文件夹的指令,首先看一下当前磁盘的剩余空间“df”指令然后执行删除后再看磁盘剩余空间我们发现,磁盘恢复了原来b占用的6kb大小,切树形图显示b已经被删除接下来我们删除a文件试一下运行结果正如预料到的现在我们尝试一下pwd指令和cat指令吧至此,实验要求的文件及目录的操作均演示完成至于具体的代码解释,代码太长了,解释起来实在不方便,望老师谅解五、心得体会本次实验有很多遗憾1、实验开始的时候,本来想把父母节点叶节点分为两种数据结构,以便节约内存空间和效率,但最后因为删除、显示列表等操作过于复杂,所以就没有采用这种方法2、很多指令没有支持绝对路径进入,且vi指令不能在没有同名文件的情况下创建一个文件。虽然都是细节,但时间过于紧迫所以放弃了3、磁盘分为扇区、盘面等等,这些均未加以考虑,但是可以解释为磁盘内部操作为磁盘控制器所为,对操作系统隐藏。本程序直接对磁盘地址操作,就理解为逻辑地址吧。4、Tree指令。在外围该有的长线不知道该怎么连上,尝试了许多方法不奏效5、本程序最大最大的漏洞在于,无论是文件名还是目录名,只支持一个字符!!只能取名为“a”“b”“c”之类的,如果命名为“a1”、“a2”之类的就会报错。这个与我选择保存文件名的数据结构有关,使用时候需要注意!!代码#includeiostream#includestring#includevector#includecassert#includeiterator#includewindows.h#includestdio.h#includeiomanipusingnamespacestd;/*扇区大小*/#defineSECTION1/*每个磁道扇区数目*/#defineSECTION_NUM10/*磁道数目*/#defineTRACK20/*盘面*/#defineDISK_SURFACE2classInformation{public:boolis_free;intnext;};classHardDisk{public:intharddisk[SECTION*SECTION_NUM*TRACK*DISK_SURFACE];intfree;Informationinf[SECTION*SECTION_NUM*TRACK*DISK_SURFACE];HardDisk(){free=SECTION*SECTION_NUM*TRACK*DISK_SURFACE;}};HardDiskharddisk;voidInitDisk(){for(inti=0;iSECTION*SECTION_NUM*TRACK*DISK_SURFACE;i++)harddisk.inf[i].is_free=true;}classNode{public:stringname;boolis_folder;/*创建时间*/SYSTEMTIMEcreate_time;/*修改时间*/SYSTEMTIMEchange_time;/*权限属主,属组,其他*/boolmod[9];/*地址*/intaddress;/*所占空间大小*/intsize;/*父节点*/Node*pParent;/*子节点*/vectorNode*pChild;Node(conststring&name,constbool&is_folder){this-name=name;this-is_folder=is_folder;//新建立的文件或文件夹都不分配磁盘空间size=0;//设置权限,不过这里没有实现作用,因为只有一个用户if(this-is_folder==false){mod[0]=1;mod[1]=1;mod[2]=1;mod[3]=1;mod[4]=false;mod[5]=1;mod[6]=1;mod[7]=false;mod[8]=1;}/*创建时间和修改时间*/GetLocalTime(&create_time);change_time=create_time;}};/*定义全局变量。根目录*/Noderoot(/,true);/*当前所在的目录*/Node*present=&root;/*定义文件指针*/Node*pFile=NULL;/**@param1文件(目录)名,可以包含路径@param2用于储存文件(目录)名**/voidfind(conststring&name,string&temp){if(name[0]=='/'){present=&root;}intj=0;for(inti=0;iname.size();i++){if(name[i]!='/'){temp[j]=name[i];j++;}elseif(i0){j=0;intk=0;if(present-pChild.size()0){while(kpresent-pChild.size()){if(temp==present-pChild[k]-name){present=present-pChild[k];break;}elsek++;if(k==present-pChild.size()){coutnosuchfolder:temp\n;return;}}}else{coutnosuchfolder:temp\n;return;}}else;//donothing}}/**对应mkdir@param目录名,可带路径**/voidCreat(conststring&name){stringtemp=;find(name,temp);for(inti=0;ipresent-pChild.size();i++){if(temp==present-pChild[i]-name&&present-pChild[i]-is_folder==true){cout有同名文件夹\n;return;}}Node*pNew=newNode(temp,true);pNew-pParent=present;present-pChild.push_back(pNew);}/**对应cd指令@param目录名**/voidGoInto(conststring&name){if(name==/){present=&root;return;}stringtemp=;if(name[0]=='/'){present=&root;}intj=0;for(inti=0;i=name.size();i++){if(name[i]!='/'&&iname.size()){temp[j]=name[i];j++;}elseif(i0){j=0;intk=0;if(present-pChild.size()0){while(kpresent-pChild.size()){if(temp==present-pChild[k]-name){present=present-pChild[k];break;}elsek++;if(k==present-pChild.size()){coutnosuchfolder:temp\n;return;}}}else{coutnosuchfolder:temp\n;return;}}else;//donothing}}/**对应pwd指令@parampresent**/voidPrintRoute(Node*p){if(p==&root){cout/;return;}else{PrintRoute(p-pParent);coutp-name/;}return;}/**对应ls指令列出当前目录下的所有文件和目录**/voidList(){for(inti=0;ipresent-pChild.size();i++){if(present-pChild[i]-is_folder==false)coutpresent-pChild[i]-name(file)endl;elsecoutpresent-pChild[i]-nameendl;}}/**文件的详细列表列表包含文件或目录的详细信息**/voidDetailedList(){for(inti=0;ipresent-pChild.size();i++){if(present-pChild[i]-is_folder==true){coutpresent-pChild[i]-name(folder)present-pChild[i]-sizeKB;}else{coutpresent-pChild[i]-namepresent-pChild[i]-sizeKB;for(intj=0;j9;j++){if((j+3)%3==0){if(present-pChild[i]-mod[j]==1)coutr;elsecout-;}elseif((j+3)%3==1){if(present-pChild[i]-mod[j]==1)coutw;elsecout-;}elseif((j+3)%3==2){if(present-pChild[i]-mod[j]==1)coutx;elsecout-;}}cout;}coutpresent-pChild[i]-change_tim