




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
长沙理工大学继续教育学院操作系统课程设计年级:专业:计算机科学与技术姓名:学号:指导老师:时间:2018年月日 模拟Linux文件系统目录一、课程设计任务书 1二、课程设计内容 21、详细设计及编码 51.1初始化命令——format 91.2系统初始化——自动完成 101.3建立文件——mffilename 101.4建立子目录——mdfilename 111.5打开文件——openfilename 121.6删除文件——delfilename 141.7删除目录——rdfilename 151.8显示目录——dir(即显示目录下的信息,包括文件、子目录等) 151.9正常退出指令exit 16三、存在问题及改进意见 39四、参考资料 39 一、课程设计任务书模拟Linux文件系统。在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的模拟Linux文件系统。1.在现有机器硬盘上开辟20M的硬盘空间,作为设定的硬盘空间。2.编写一管理程序对此空间进行管理,以模拟Linux文件系统,具体要求如下:(1)要求盘块大小1k正规文件(2)i结点文件类型目录文件(共1byte)块设备管道文件物理地址(索引表)共有13个表项,每表项2byte文件长度4byte。联结计数1byte(3)0号块超级块栈长度50空闲盘块的管理:成组链接(UNIX)位示图法(Linux)(4)每建一个目录,分配4个物理块文件名14byte(5)目录项信息i结点号2byte(6)结构:0#:超级块1#-20#号为i结点区20#-30#号为根目录区3.该管理程序的功能要求如下:(1)能够显示整个系统信息,源文件可以进行读写保护。目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开。(2)改变目录:改变当前工作目录,目录不存在时给出出错信息。(3)显示目录:显示指定目录下或当前目录下的信息,包括文件名、物理地址、保护码、文件长度、子目录等(带/s参数的dir命令,显示所有子目录)。(4)创建目录:在指定路径或当前路径下创建指定目录。重名时给出错信息。(5)删除目录:删除指定目录下所有文件和子目录。要删目录不空时,要给出提示是否要删除。(6)建立文件(需给出文件名,文件长度)。(7)打开文件(显示文件所占的盘块)。(8)删除文件:删除指定文件,不存在时给出出错信息。4.程序的总体流程为:(1)初始化文件目录;(2)输出提示符,等待接受命令,分析键入的命令;(3)对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令,直到键入EXIT退出为止。二、课程设计内容在现有机器硬盘上开辟20M的硬盘空间(利用一个循环操作,在Disk中写入20M的零,创建一个20M的文件即是),作为设定的硬盘空间。 磁盘块物理模型如下:空闲盘块栈(存放空闲盘块)空闲盘块栈(存放空闲盘块)目录区各盘块(每个占1KB)存放文件内容,为程序设计方便,iNode节点也存放在此处。1kb(目录快)30kB20480kb0kb(超级块信息)文件则是指具有文件名的若干相关元素的集合。文件属性主要如下文件名:实现了按名存取,文件名和目录文件允许重名。文件类型:可以从不同的角度来规定文件的类型。普通文件、管道文件、块文件。文件长度:指文件的当前长度,长度的单位可以是KB。文件的物理位置:文件在磁盘中物理的存储,并打印出来。此次UNIX文件系统最简单的目录结构。整个文件系统中只建立一张目录表,每个文件一个目录项,目录项含有文件相关信息。每建立一个新文件要先检索所有的目录项保证文件名唯一。然后找出一空白目录项填入相关信息,并修改状态位。删除文件是找到对应目录项,回收所占用空间,清除该目录。逻辑结构如下文件名索引节点编号文件名1INode文件名2INode文件名3INode….…. Unix文件系统当文件很多时,文件目录要占用大量的盘块。在查找目录的过程中,可能需要多次启动磁盘读入目录文件的盘块。在检索目录文件中只用到了文件名,显然,文件的物理地址等文件的描述信息在检索目录时不需调入内存。为此,可以把文件名与文件描述信息分开。使文件描述信息单独形成一个索引结点。把文件描述信息单独形成一个称为索引结点的数据结构,简称为inode;文件目录中的每个目录项,则仅由文件名及指向该文件所对应的inode的指针所构成。这样,为找到一个文件的平均启动磁盘的次数减少很多模型如下:RootFan.txtINodeINode节点目录节点节点INode节点目录节点节点INode节点AB存储空间的分配与回收成组链接法首先,建立操作系统课程的设计模型。这个系统将利用一个20M的文件作为自己的磁盘空间,设计时由于一个盘块占用1KB,所以20M空间可以产生20480个盘块系统本身将0#-30#块作为系统区,所以用户区便剩下20450个盘块,每50个盘块为一组,一共可以分为409个组。将每一组含有的盘块总数N和该组的盘块号,记入其前一组的第一个盘块的S.free(1)~S.free(50)。这样由各组的第一个盘块形成了一条链。将第一组的盘块总数和所有的盘块号,记入空闲盘块号栈中,作为当前可供分配的空闲盘块号。最末一组只有49个盘块,其盘块号分别记入其前一组的S.free(1)~S.free(99)中,而在S.free(0)中则存放0,作为空闲盘块链的结束标志。基本功能:初始化;建立文件;建立子目录;打开文件;删除文件;删除目录;显示目录1、详细设计和编码正规文件i结点文件类型目录文件(共1byte)块设备管道文件。物理地址(索引表)共有13个表项,每表项2byte。文件长度4byte。联结计数1bytestructINode{ FileSpecfileSpec; shortiaddr[13]; intfileLength; intlinkCount;};文件名14byte(5)目录项信息i结点号2bytestructDirChild{charfilename[14];shorti_BNum;};structDirNode{DirChildchildItem[64];short DirCount;};定义磁盘文件名constcharFileName[]="os.txt";默认为空的文件名constcharNullName[]="0000000000000";默认目录文件的长度constintDirLen=1;默认超级块的快号constshortSSNum=-1; //superblocknum定义枚举类型,普通,目录,块文件,管道文件enumFileSpec{NORMAL,DIR,BLOCK,PIP};//0,1,2,3shortSS[51]; //超级栈,指针为SS[0],保存当前可用盘快shortfreeBlockNum=0; //当前可用盘快所在组记录的盘快号shortfreeTotalB=20450; 文件总长度shortfreeDirNode[29]; //可用索引节点栈shortfreeDirCount=30; //索引节点栈指针shortcurrDirNum; //当前目录所在的磁盘号shortcurrINum; DirNode*currDir; //当前目录节点INode *iNode; //当前iNode
节点系统调用函数列表系统调用原型功能入口、出口参数说明VoidArrarEqual(shortarr[51],shortbegin,shortend)arr[51]数组赋值,在成组链接初始化时使用voidBWrite(shortarr[51],shortdiskNum)往磁盘中写入短数组voidBWriteArr(shortarr[512],shortdiskNum)重构BWrite,实现一个数组的写入,数组长度不确定voidBRead(INode*iNode,shortdiskNum)从磁盘中读出iNode节点voidBRead(shortarr[51],shortdiskNum)从磁盘中读出数组voidBReadArr(shortarr[512],shortdiskNum)从磁盘中读出数组,成组链接多级索引使用BWrite(DirNode*currDir,shortdiskNum)写入一个目录项VoidBWrite(INode*iNode,shortdiskNum)写入一个iNodeVoidAssAnEmpty()分配一个空闲的普通快shortAssAnDir()分配一个空闲的目录快shortIsFileExist(DirNode*currDir,charfileName[14])判断一个文件是否存在-1不存在,否则返回文件所在磁盘号boolIsFile(INode*iNode,shortdiskNum)判断一个文件是一个普通文件boolIsDir(INode*iNode,shortdiskNum)判断一个文件是一个索引文件voidCreateINode(INode*iNode,FileSpecfileSpec,shortlinkCount,shortlength)创建一个iNode,并分配磁盘空间voidCleanINode(INode*iNode)清空iNode信息,并分配磁盘空间voidInsertDir(DirNode*currDir,charfileName[14],shortblockNum)将当前目录项插入到内存中目录项中voidShowFileInfo(INode*iNode,charfileName[14])打开一个文件,显示文件信息voidShowBlockInfo(INode*iNode)打开一个文件,显示文件占用磁盘空间信息voidDelDirItem(DirNode*currDir,charfileName[14])删除索引中一项voidCallBackOne(shortdiskNum)回收一块空余磁盘片voidCallBackINode(shortdiskNum)回收文件的iNOde节点主要函数列表函数原型功能入口、出口参数说明Format创建20M磁盘voidInit(DirNode*currDir,FileSpecfielSpec,charfilename[14],INode*iNode,shortdiskNum)初始化,创建个目录节点并初始化超级栈Init()初始化索引栈voidLinkdisk()成组链接初始化voidInitCreate(DirNode*currDir,FileSpecfielSpec,charfilename[14],INode*iNode,shortdiskNum)创建一个文件节点,并分配INOde和磁盘空间voidCreate(DirNode*currDir,charfileName[14],INode*iNode,shortlength,FileSpecfileSpec)存在文件,并分配iNOde节点和磁盘空间voidMf(DirNode*currDir,charfileName[14],INode*iNode,shortlength)创建一个文件voidMd(DirNode*currDir,charfileName[14],INode*iNode,shortlength)在当前目录创建一个子目录voidOpen(DirNode*currDir,charfileName[14],INode*iNode)打开文件,显示文件信息voidDel(DirNode*currDir,charfileName[14],INode*iNode)删除一个文件voidRd(DirNode*currDir,charfileName[14],INode*iNode)删除一个目录voidDir(DirNode*currDir,INode*iNode)显示目录项的内容voidexit(DirNode*currDir,INode*iNode)退出,并销毁资源voidAuthorMessage()打印版权信息voidhelp()提示信息主框架开开始打印作者信息初始化磁盘合法性检查输入命令显示:命令错误falseo有新建文件新建目录打开文件删除文件删除目录显示目录立退出1.1初始化命令——format利用文件创建命令可在硬盘上创建一个名为Disk的20M的空间,并将该磁盘空间整体假想成一个独立硬盘,我们将在这张封闭的磁盘上进行各种关于文件的操作。Format具体操作如下:利用一个循环操作,在Disk中写入20M的零。然后将0#块,即超级块中写入31#-80#的盘块号,并将全部可用剩余盘块数FreeBlock=20450记录在0#块中。同时将80#,130#,180#(间距50)等408个(第409个组头不存在下一组)盘组的组头中写入成组连接好的下一组盘块号。1.2系统初始化——自动完成假如Disk已被格式化完毕,那么系统便将进行下一步,那就是初始化。初始化主要完成将根目录项读入内存,便于文件操作,并将0#超级块中保存的当前可用盘块号写入内存中的超级栈中,具体操作如下:初始化一个超级栈,将超级块中保存的当前可分配盘块号读入栈中。定义一个全局变量FreeBlock,用来记录当前全部可用的盘块总数。1.3建立文件——mffilename如果终端发来的命令格式为mffilename,则可以判断出这是建立文件的命令。要想成功建立一个文件,首先需要判断在同级目录下是否有重名的文件,并且需要判断是否有足够的空间允许建立一个指定长度的文件。mf(代表makefile)具体操作如下:(1)判断所要建立的文件是否重名。首先将终端输入的文件名filename在RootDir[640]进行检索,看是否可以找到相同的名字,假如找到了相同的名字还不能立刻判断是重名了,因为同级目录下允许文件夹与文件重名,然后利用DirItem结构中的最后2个Byte要找到暂时重名文件的i结点,从i结点中读出该文件的属性,看是为正规文件还是文件夹。如果重名了,系统会提示,否则进行下一步。(2)如果不重名,则要根据用户输入的文件长度来判断当前的剩余盘块总数是否足够分配,这项工作不仅仅是用终端输入来的length与剩余盘块总数FreeBlock比较,因为Unix本身采取混合索引方式,所以根据文件的长度会分配不同的索引盘块数。所以判断盘块数是否足够同时要计算出相应的索引盘块数。如果文件数据本身盘块数加上相应的索引盘块数不会超过总剩余盘块数,则可进行分配。开开始获得文件名获得文件名获得文件长度获得文件长度合法性检查合法性检查返返回分配目录项分配磁盘空间分配磁盘空间分配索引节点分配索引节点返返回1.4建立子目录——mdfilename建立子目录,即建立一个文件夹。其可以看作是建立文件的一个特殊情况,建立一个文件夹的过程和上述的建立文件非常相似,也要判断重名,也要判断是否盘块数足够分配,以及分配时所要考虑到的全部情况(文件夹利用0级索引)。开开始获得目录名获得目录名读取目录节点读取目录节点合法性检查合法性检查返返回创建创建iNode,分配索引节点分配磁盘空间分配磁盘空间分配目录项分配目录项返返回1.5打开文件——openfilename(显示文件所占的盘块)开开始检查当前目录目录中有文件么?检查iNode文件属性与操作类型相符?打开文件:显示文件信息打印iNode中盘快信息显示:“打开”成功返回显示:不存在该文件,打开失败返回显示:文件类型不匹配返回有无否是读取iNode这个命令就是所谓的读文件命令,在这个模拟Unix的系统中,我们将显示文件所占的盘块以及文件的相关信息。要打开文件,当然首先要判断是否有这样一个文件名,然后才是读出全部的盘块数1.6删除文件——delfilename开始查该用目录表currDircurrDir中有该文件?检查iNode文件类型匹配?归还文件所占的存储区域在UFD中清除该文件登记栏在清除iNode信息,释放磁盘节点currDir中清除该文件的登记栏显示:文件已撤消是是否返回开始查该用目录表currDircurrDir中有该文件?检查iNode文件类型匹配?归还文件所占的存储区域在UFD中清除该文件登记栏在清除iNode信息,释放磁盘节点currDir中清除该文件的登记栏显示:文件已撤消是是否返回返返回删除文件同创建文件都是非常复杂的操作,要有多种情况需要考虑。要想成功删除一个文件,首先需要判断在同级目录下是否有该文件名,然后在根据该文件为几级索引文件进行相应的回收1.7删除目录——rdfilename就如同建立目录好似建立文件的一种特殊情况,删除目录也和删除文件差不多,但是有一点是绝对不同的,要特别注意。当子目录下建立了文件或者文件夹时,即表示子目录不为空,那么系统本身为了保持数据的完整性,是不对该目录进行删除操作的,而提示用户该目录不为空。除非用户删除了该目录下的全部文件后,返回到根目录,此时子目录为空,才允许系统删除该文件夹。删除时的具体过程同删除0级索引文件极为相似,这里就不作过多说明。文件流程如删除文件,此处不再赘述。1.8显示目录——dir(即显示目录下的信息,包括文件、子目录等)Dir是一个很容易实现的命令,在目录下输入此命令,即可以获得目录下的信息,包括文件、子目录等。开开始读取当前目录读取iNode显示完所有目录显示文件信息打印iNode中显示:成功返回否是1.9正常退出指令exit不要小看了这条指令,它可以帮你完成许多被你遗忘的操作,由于此次代码编写超过了3000行,而且涉及到大量的文件操作函数,所以难免会对文件的关闭,栈的释放等结束工作考虑不周全,为了提高数据的可靠性与完整性,建议退出系统时用此命令,它可以自动完成文件的关闭。程序源代码#include<fstream>#include<iostream>#include<string>usingnamespacestd;constcharFileName[]="os.txt";constcharNullName[]="0000000000000";constintDirLen=1;constshortSSNum=-1; //superblocknumenumFileSpec{NORMAL,DIR,BLOCK,PIP};//0,1,2,3//i节点结构信息structINode{ FileSpecfileSpec; shortiaddr[13]; intfileLength; intlinkCount;};structDirChild{charfilename[14];shorti_BNum;};structDirNode{DirChildchildItem[64];short DirCount;};shortSS[51]; //超级栈,指针为SS[0]shortfreeBlockNum=0; //当前可用盘快所在组记录的盘快号shortfreeTotalB=20450;shortfreeDirNode[29]; //可用索引节点栈shortfreeDirCount=30; //索引节点栈指针shortcurrDirNum; //当前目录所在的磁盘号shortcurrINum;DirNode*currDir;INode *iNode;//================================================================//函数描述:创建20M磁盘//入口参数:无//返回值:无//===============================================================voidFormat(){ cout<<"系统正在初始化"<<endl; //打开文件 FILE*f=fopen(FileName,"w+"); if(f==NULL) { cout<<"程序创建错误,请重新输入"<<endl; return; } for(inti=0;i<20971520;i++)//20971520=20Mb,暂时2mb fprintf(f,"%c",'0'); //关闭文件 fclose(f);}//================================================================//函数描述:数组赋值//入口参数:无//返回值:无//===============================================================voidArrarEqual(shortarr[51],shortbegin,shortend){ for(shorti=0;i<end-begin+1;i++) arr[50-i]=begin+i;}//================================================================//函数描述:数组赋值//入口参数:无//返回值:无//===============================================================/*voidBWrite(shortarr[51],shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"写文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; fwrite(arr,sizeof(short),51,f); fclose(f); }*///================================================================//函数描述:重构BWrite,实现一个数组的写入//入口参数:无//返回值:无//===============================================================voidBWrite(shortarr[51],shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"写文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; fwrite(arr,sizeof(short),51,f); fclose(f); }//================================================================//函数描述:重构BWrite,实现一个数组的写入,数组长度不确定//入口参数:无//返回值:无//===============================================================voidBWriteArr(shortarr[512],shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"写文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; fwrite(arr,sizeof(short),512,f); fclose(f); }//================================================================//函数描述:重构BWrite,实现一个数组的写入//入口参数:无//返回值:无//===============================================================voidMyBWrite(shortarr[51],shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"写文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; for(shorti=0;i<51;i++) fprintf(f,"%d",arr[i]); fclose(f); }//================================================================//函数描述:从磁盘中读出数组//入口参数:无//返回值:无//===============================================================voidMyBRead(shortarr[51],shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"读文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; for(shorti=0;i<51;i++) fscanf(f,"%d",&arr[i]); fclose(f); }//================================================================//函数描述:从磁盘中读出iNode节点//入口参数:无//返回值:无//===============================================================voidBRead(INode*iNode,shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"写文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; fscanf(f,"%d",&iNode->fileLength); inttemp=int(fgetc(f)); switch(temp){ case0: iNode->fileSpec=NORMAL; break; case1: iNode->fileSpec=DIR; break; case2: iNode->fileSpec=BLOCK; break; case3: iNode->fileSpec=PIP; break; } fread(iNode->iaddr,2,13,f); fscanf(f,"%d",&iNode->linkCount); fclose(f); }//================================================================//函数描述:从磁盘中读出数组//入口参数:无//返回值:无//===============================================================voidBRead(shortarr[51],shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"读文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; fread(arr,sizeof(short),51,f); fclose(f); }//================================================================//函数描述:从磁盘中读出数组,放入到iNOde中//入口参数:无//返回值:无//===============================================================voidBReadArr(shortarr[512],shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"读文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; fread(arr,sizeof(short),512,f); fclose(f); }//================================================================//函数描述:写入一个目录项//入口参数:无//返回值:无//===============================================================voidBWrite(DirNode*currDir,shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"写文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,long(1024*diskNum),0)) cout<<"文件指针错误"<<endl; for(inti=0;i<64;i++) { fprintf(f,"%hd",currDir->childItem[i].i_BNum); fputs(currDir->childItem[i].filename,f); } fclose(f); }//================================================================//函数描述:写入一个iNode//入口参数:无//返回值:无//===============================================================voidBWrite(INode*iNode,shortdiskNum){ FILE*f=fopen(FileName,"r+"); if(f==NULL) { cout<<"写文件处错误,请重新输入"<<endl; return; } //设置文件指针 if(fseek(f,1024*diskNum,0)) cout<<"文件指针错误"<<endl; fprintf(f,"%d",iNode->fileLength); fputc(iNode->fileSpec,f); fwrite(iNode->iaddr,2,13,f); fprintf(f,"%d",iNode->linkCount); fclose(f); }//================================================================//函数描述:分配一个空闲的普通快//入口参数:无//返回值:无//===============================================================shortAssAnEmpty(){ shorttemp; if(SS[0]>1){ SS[0]--; temp=SS[SS[0]+1];// SS[SS[0]+1]=-1; freeTotalB--;//总剩余数-1 returntemp; }else{ if(SS[1]==0){ cout<<"盘片用尽"<<endl; return-1; } temp=freeBlockNum; freeBlockNum=SS[1]; BRead(SS,SS[1]); if(temp==0){ SS[0]--; temp=SS[SS[0]+1];// SS[SS[0]+1]=-1; } freeTotalB--; returntemp; } }//================================================================//函数描述:分配一个空闲的目录快//入口参数:无//返回值:无//===============================================================shortAssAnDir(){ if(freeDirCount==0){ cout<<"无空余目录节点"<<endl; return-1; } else{ freeDirCount--; shorts=freeDirNode[freeDirCount]; freeDirNode[freeDirCount]=-1; returns; //可用索引节点栈 } }//================================================================//函数描述:创建一个文件节点,并分配INOde和磁盘空间//入口参数:无//返回值:无//===============================================================voidInitCreate(DirNode*currDir,FileSpecfielSpec,charfilename[14],INode*iNode,shortdiskNum){ // intblockNum=AssertAnEmpty(); if(fielSpec==DIR){ //initdirNodeandwrite intblockNum=AssAnDir(); currDirNum=blockNum; for(inti=0;i<64;i++){ strcpy(currDir->childItem[i].filename,"0000000000000"); currDir->childItem[i].i_BNum=-1; } BWrite(currDir,blockNum);/* //initINodeandwrite blockNum=AssertAnEmpty(); iNode->fileLength=DirLen; iNode->fileSpec=DIR; iNode->iaddr[0]=blockNum; iNode->linkCount=1; BWrite(iNode,distNum); //为文件分配磁盘空间*/ }//endif(fileSpec==DIR) }//================================================================//函数描述:初始化//入口参数:无//返回值:无//===============================================================voidInit(DirNode*currDir,FileSpecfielSpec,charfilename[14],INode*iNode,shortdiskNum){ InitCreate(currDir,fielSpec,filename,iNode,diskNum); BRead(SS,0);}//================================================================//函数描述:初始化索引栈//入口参数:无//返回值:无//===============================================================voidInit(){for(inti=0;i<30;i++)freeDirNode[i]=30-i; //可用索引节点栈freeDirCount=30; //索引节点栈指针 }//================================================================//函数描述:成组链接初始化//入口参数:无//返回值:无//===============================================================voidLinkdisk(){ //临时空闲栈 SS[0]=50; ArrarEqual(SS,31,80); BWrite(SS,0); for(shorti=1;i<408;i++){ SS[0]=50; ArrarEqual(SS,i*50+31,i*50+80); BWrite(SS,i*50+30); BRead(SS,0); } ArrarEqual(SS,408*50+31,408*50+79); SS[1]=0;//49 BWrite(SS,408*50+30); cout<<"磁盘disk.txt完成创建,大小20MB"<<endl; }//================================================================//函数描述:判断一个文件是否存在//入口参数:无//返回值:-1,不存在,文件号//===============================================================shortIsFileExist(DirNode*currDir,charfileName[14]){ for(inti=0;i<64;i++){ if(strcmp(fileName,currDir->childItem[i].filename)==0) returncurrDir->childItem[i].i_BNum; } return-1;}//================================================================//函数描述:判断一个文件是一个普通文件//入口参数:无//返回值:-1,不存在,文件号//===============================================================boolIsFile(INode*iNode,shortdiskNum){ BRead(iNode,diskNum); if(iNode->fileSpec==NORMAL) returntrue; else returnfalse;}//================================================================//函数描述:判断一个文件是一个普通文件//入口参数:无//返回值:-1,不存在,文件号//===============================================================boolIsDir(INode*iNode,shortdiskNum){ BRead(iNode,diskNum); if(iNode->fileSpec==DIR) returntrue; else returnfalse;} //================================================================//函数描述:创建一个iNode,并分配磁盘空间//入口参数:无//返回值:无AssAnEmpty(),BWrite(dirChild,dir[512-i])未实现//===============================================================voidCreateINode(INode*iNode,FileSpecfileSpec,shortlinkCount,shortlength){ iNode->fileSpec=fileSpec; iNode->linkCount=linkCount; iNode->fileLength=length; //为目录磁盘,分配目录节点 if(fileSpec==DIR){ iNode->iaddr[0]=AssAnDir(); return; } //根据文件长度分配文件磁盘节点 //直接寻址 shorti; i=10; shortleft=length; while(left&&i){ iNode->iaddr[10-i]=AssAnEmpty(); left--; i--; } if(left>0){ //一级索引 i=512; shortdir[512]; iNode->iaddr[10]=AssAnEmpty(); while(left&&i){ dir[512-i]=AssAnEmpty(); i--; left--; } if(i!=0) dir[512-i+1]=-1;//标志文件结束 BWriteArr(dir,iNode->iaddr[10]); if(left>0){ //二级索引 shortk=512; shortj=512; shortdirChild[512]; iNode->iaddr[11]=AssAnEmpty(); while(left&&k){ //二级索引1次寻址 dir[512-k]=AssAnEmpty(); while(left&&j){ //二级索引二次寻址 dirChild[512-j]=AssAnEmpty(); left--; j--; } if(j!=0) dir[512-j+1]=-1; //标志二级索引二次寻址结束 BWriteArr(dirChild,dir[512-k]); BWriteArr(dir,iNode->iaddr[11]);//写二级索引一次寻址中盘快记录的一次寻的盘快号 k--; } if(k!=0) dir[512-k+1]=-1;//标志文件结束 } }}//================================================================//函数描述:清空iNode信息,并分配磁盘空间//入口参数:无//返回值:无AssAnEmpty(),BWrite(dirChild,dir[512-i])未实现//===============================================================voidCleanINode(INode*iNode){ iNode->fileSpec=PIP; iNode->linkCount=-1; iNode->fileLength=-1; //根据文件长度非配文件磁盘节点 //直接寻址 for(shorti=0;i<13;i++) iNode->iaddr[i]=-1; }//================================================================//函数描述:创建一个iNode,并分配磁盘空间//入口参数:无//返回值:无//===============================================================voidInsertDir(DirNode*currDir,charfileName[14],shortblockNum){ strcpy(currDir->childItem[currDir->DirCount].filename,fileName); currDir->childItem[currDir->DirCount].i_BNum=blockNum; currDir->DirCount++; return;}//================================================================//函数描述:存在文件,并分配iNOde节点和磁盘空间//入口参数:无//返回值:无//===============================================================voidCreate(DirNode*currDir,charfileName[14],INode*iNode,shortlength,FileSpecfileSpec){ intblockNum; if(length>freeTotalB){ cout<<"当前文件超出长度"<<endl; return; } CreateINode(iNode,fileSpec,0,length); blockNum=AssAnEmpty();//分配一个空余磁盘存储iNOde InsertDir(currDir,fileName,blockNum); BWrite(iNode,blockNum); CleanINode(iNode); BWrite(currDir,currDirNum);//此处}//================================================================//函数描述:创建一个文件,//入口参数:无//返回值:无//===============================================================voidMf(DirNode*currDir,charfileName[14],INode*iNode,shortlength){ intblockNum=IsFileExist(currDir,fileName); if(blockNum!=-1){//有重名名,进一步判断 if(IsFile(iNode,blockNum)) cout<<"当前文件已经存在,请重新输入文件名"<<endl; }else{//存在文件,为索引文件,或者无重名现象,创建文件,并分配iNOde节点和磁盘空间 //BRead(iNode,1059);//此处出错 Create(currDir,fileName,iNode,length,NORMAL); } }//================================================================//函数描述:在当前目录创建一个子目录//入口参数:无//返回值:无//===============================================================voidMd(DirNode*currDir,charfileName[14],INode*iNode,shortlength){ intblockNum=IsFileExist(currDir,fileName); if(blockNum!=-1){//有重名名,进一步判断 if(IsDir(iNode,blockNum)) cout<<"当前目录已经存在,请重新输入目录名"<<endl; }else{//存在文件但为普通文件,或者无重名现象。创建文件,并分配iNOde节点和磁盘空间 Create(currDir,fileName,iNode,length,DIR); CleanINode(iNode); } }//================================================================//函数描述:打开一个文件,//入口参数:无//返回值:无//=============================================================== voidShowBlockInfo(INode*iNode){ shortdir[512]; shorti; i=10; shortleft=iNode->fileLength; while(left&&i){ cout<<(iNode->fileLength-left)<<":"<<iNode->iaddr[10-i]<<""; left--; i--; } if(left>0){ i=512; shortdir1[512]; BReadArr(dir1,iNode->iaddr[10]); while(left&&i){ cout<<(iNode->fileLength-left)<<":"<<dir1[512-i]<<""; i--; left--; } } if(left>0){ //二级索引 shortk=512; shortj=512; shortdirChild[512]; BReadArr(dir,iNode->iaddr[11]); while(left&&k){ //二级索引1次寻址 BReadArr(dirChild,dir[512-k]); while(left&&j){ //二级索引二次寻址 cout<<(iNode->fileLength-left)<<":"<<dirChild[512-j]<<""; left--; j--; } k--; } } }//================================================================//函数描述:打开一个文件,//入口参数:无//返回值:无//=============================================================== voidShowFileInfo(INode*iNode,charfileName[14]){ cout<<"文件名"<<fileName; cout<<"文件类型"; switch(iNode->fileSpec){ caseNORMAL: cout<<"<文件>"; break; caseDIR: cout<<"<目录>";break; caseBLOCK: cout<<"<INode节点>";break; casePIP: cout<<"管道";break; } cout<<""<<iNode->fileLength<<"KB"<<endl;}//================================================================//函数描述:打开一个文件,//入口参数:无//返回值:无//===============================================================voidOpen(DirNode*currDir,charfileName[14],INode*iNode){ intblockNum=IsFileExist(currDir,fileName); if(blockNum==-1){//不存在该文件,退出 cout<<"该文件按不存在"<<endl; return; } else{ if(IsFile(iNode,blockNum)){ ShowFileInfo(iNode,fileName); ShowBlockInfo(iNode); } } }//================================================================//函数描述:回收一块空余磁盘片//入口参数:无//返回值:无//===============================================================voidCallBackOne(shortdiskNum){ freeTotalB++; if(SS[0]<=49){ SS[0]++; SS[SS[0]]=diskNum; }else{//SS[0]==50 BWrite(SS,freeBlockNum); //将空白的一组回写到上一组记录空闲盘快号的磁盘 freeBlockNum=SS[1]; //将当前空白的一组第一个盘快作为下一个盘组的记录盘 //修改超级栈 SS[1]=diskNum; SS[0]=1; } }//================================================================//函数描述:回收文件占用的磁盘//入口参数:无//返回值:无//===============================================================voidCallBackDisk(INode*iNode){ shorti; i=10; shortleft=iNode->fileLength; while(left&&i){//直接索引回收 CallBackOne(iNode->iaddr[10-i]); left--; i--; } if(left>0){ //一级索引回收 i=512; shortdir1[512]; BReadArr(dir1,iNode->iaddr[10]); while(left&&i){ CallBackOne(dir1[512-i]); i--; left--; } CallBackOne(iNode->iaddr[10]); } if(left>0){ //二级索引 shortk=512; shortj=512; shortdir[512]; shortdirChild[512]; BReadArr(dir,iNode->iaddr[11]);//二级索引1次寻址 while(left&&k){ //二级索引1次寻址 BReadArr(dirChild,dir[512-k]); while(left&&j){ //二级索引二次回收 CallBackOne(dirChild[512-j]); left--; j--; } CallBackOne(dir[512-k]);//二级索引一次寻址 k--; } CallBackOne(iNode->iaddr[11]); } }//================================================================//函数描述:回收文件的iNOde节点//入口参数:无//返回值:无//===============================================================voidCallBackINode(shortdiskNum){ CallBackOne(diskNum); }//================================================================//函数描述:删除索引中一项//入口参数:无//返回值:-1,不存在,文件号//===============================================================voidDelDirItem(DirNode*currDir,charfileName[14]){ for(inti=0;i<64;i++){ if(strcmp(fileName,currDir->childItem[i].filename)==0){ // currDir->DirCount--; strcpy(currDir->childItem[i].filename,NullName); currDir->childItem[i].i_BNum=-1; return; } } cout<<"删除失败"<<endl;}//================================================================//函数描述:删除一个文件//入口参数:无//返回值:无//===============================================================voidDel(DirNode*currDir,charfileName[14],INode*iNode){ shortblockNum=IsFileExist(currDir,fileName); if(blockNum==-1){//不存在该文件,退出 cout<<"文件不存在,删除失败"<<endl; }else{ if(IsFile(iNode,blockNum)){ CallBackDisk(iNode); DelDirItem(currDir,fileName); CleanINode(iNode); }else{ cout<<"文件不存在,删除失败"<<endl; } } }//================================================================//函数描述:删除一个目录//入口参数:无//返回值:无//===============================================================voidRd(DirNode*currDir,charfileName[14],INode*iNode){ shortblockNum=IsFileExist(currDir,fileName); if(blockNum==-1){//不存在该文件,退出 cout<<"目录不存在,删除失败"<<endl; }else{ if(IsDir(iNode,blockNum)){ CallBackDisk(iNode); DelDirItem(currDir,fileName); CleanINode(iNode); }else{ cout<<"目录不存在,删除失败"<<endl; } } }//================================================================//函数描述:显示目录项的内容//入口参数:无//返回值:无//===============================================================voidDir(DirNode*currDir,INode*iNode){ for(inti=0;i<currDir->DirCount;i++){ if(currDir->childItem[i].i_BNum!=-1){ BRead(iNode,currDir->childItem[i].i_BNum); ShowFileInfo(iNode,currDir->childItem[i].filename); } CleanINode(iNode); }}//================================================================//函数描述:销毁资源//入口参数:无//返回值:无//===============================================================voidexit(DirNode*currDir,INode*iNode){ deleteiNode; deletecurrDir;}//=======================================================
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宁夏银川十五中2025年中考语文试题命题比赛模拟试卷(31)含解析
- 江西水利职业学院《越南语初级听说》2023-2024学年第一学期期末试卷
- 成人教育终身学习体系构建与平台运营:2025年行业痛点与解决方案研究
- 劳务合同标准文本钟
- 劳务合同标准文本小时工
- 食品与饮料行业有机食品消费趋势及市场潜力
- 到期结算合同标准文本
- 劳务防水合同标准文本
- 包船运输货物合同标准文本
- 医院招聘护士合同样本
- 全新三方居间协议范本下载(2024版)
- DL∕T 5494-2014 电力工程场地地震安全性评价规程
- 教育公平问题案例
- 2024年北京卫生职业学院高职单招笔试历年职业技能测验典型例题与考点解析含答案
- 企业保密意识培训课件
- 2024版《供电营业规则》学习考试题库500题(含答案)
- 2024年山东省烟台市开发区中考数学一模试卷
- MOOC 现代邮政英语(English for Modern Postal Service)-南京邮电大学 中国大学慕课答案
- Unit 5 Feeling excited Topic 2 Section D 示范公开课教学课件【八年级英语下册仁爱版】
- 生命科学导论(中国农业大学)智慧树知到期末考试答案2024年
- 2024年辽宁省大连理工附中中考物理模拟试卷
评论
0/150
提交评论