模拟unix文件系统一、基本信息完成人:牛娜(2006116242)报告日期:2008-3-24二、试验要求1.文件系统应具有的基本功能(1)多用户:usr1,usr2(2个用户)(2)多级目录:具有树形目录结构;(3)具有login(用户登录)和用户身份认证功能;(4)文件的创建:create(5)文件的打开:open(6)文件的读:read(7)文件的写:write(8)文件关闭:close(9)删除文件:delete(10)创建目录(建立子目录):mkdir(11)改变当前目录:cd(12)列出文件目录:dir(列目录时要列出文件名、物理地址和文件长度)(13)退出:logout(14)有文件保护机制,如对文件设置访问权限等(如用户usr1不能对usr2创建的文件进行修改等)。2.选用程序设计语言:C或C++等。3.注意界面友好,有提示信息!三、设计思想说明课程设计所利用的空间为1M的内存(模拟外存文件系统存储空间),模拟外存文件系统存储空间。这1M内存分成512块,每块为512个字节,这512块就是文件系统总共的可用块数,文件系统的分配就是以块为单位来分配的,文件是以成组链接进行管理。四相关数据结构说明4.1用来存放用户所能输入的各种命令。structcommand{charcom[10];}cmd[17];4.2模拟的外存文件系统的存储空间,有512块内存,n代表空闲块的个数,free[50]代表存放空闲盘块的地址,a代表模拟的盘块是否被占用。structblock{intn;intfree[50];inta;}memory[512]4.3存放文件的数据体,1M内存中structfile_block{charp[100];}fileBlock[];4.4超级块中的数据结构包含用来存放空闲盘块的个数,存放进入栈中的空闲块,下一组空闲盘块的地址。structblock_super{intn;intfree[50];intstack[50];}super_block;4.5文件的i节点信息,它包括文件类型,文件长度,用户对该文件的操作权限,文件中的用户和同组用户和文件的物理地址。structnode{intfile_style;intfile_length;intfile_mode;intfile_userid;intfile_groupid;intfile_address[10];}i_node[512];4.6用来存放目录项的信息,fli_name表示文件名,i_num表示文件的节点号,dir_name表示文件所在的目录。structdir{charfile_name[10];inti_num;chardir_name[10];}root[512];4.7活动节点,存放节点的个数和节点号structactive_node{structnodefile_node;inti_count;inti_number;}ActiveNode[30];4.8用户文件表,文件的位置structuser_file_table{intlocation[15];}UserFileTable[2];4.9系统文件表,文件名和共享技术structsystem_file_table{charfilename[10];intpointer;}SystemFileTable[30];五各模块的流程图5.1用户登录模块设置用户名和密码,用来验证登录用户的身份,用户登录成功前会初始化当前用户等一系列的系统当前信息,用户的类型为普通用户,如果用户未能通过身份验证,提示用户登失败,可重新登陆两次。开始输入次数是否大于2输入用户名和密码存在此用户没Currentuser=User1存在NoNo对比起,不是系统用户Yse5.2创建文件功能只支持在当前目录创建文件,找到个未使用的文件块用来存放用户的文件信息,同时更文件索引i开始遍历块数超过512存在文件不文件存在,不许建立重名的文件遍历块数i_节点号是否没有分配?I节点的内容进行修改,插入文件的系统文件表里分配空间是否在长度范围之内文件缓冲地址的内容赋予文件的物理地址退出NoYes\NoYesNoYes5.3文件打开功能只支持在当前目录进行操作,通过用户给定的文件名进行判断是否是文件,打印出文件的属性。开始块遍历i节点赋予k打开的是否为文件打印文件的属性判断文件的长度是否超过打开文件的盘快号插入到文件表是否为512块无此文件打印占用的盘块号YesNoYes遍历完5.4文件读取功能只支持在当前目录进行操作,只准在已创建的文件中进行写操作,并以D结束输入。打开文件表看存在文件存在文件不?操作违法不遍历块?文件的权限赋予address块遍历完打印内容打印出错遍历块数结束?存在此文件不i节点赋予文件的节点号块遍历完?块号赋予address是否由此权限遍历块结束?无此权限打印其内容YesNoYesNoYesYesNoNoNoYesYesNoYesNo5.5文件的写功能在已经创建好的文件中输入内容,以D结束输入。打开文件存在存在文件不操作是否违法是否输入内容块遍历是否完缓冲区的内容拷到文件块是否遍历完输入完毕,将长度赋予文件遍历文件的长度是否结束?请输入内容,文件以D结束文件写满无权限块是否遍历完存在此文件不插入到系统文件表是否有权限找不到文件块是否遍历完块地址赋予addressYesNoYesYesNoYesNoNoYesNoYesNoYesYesNoNo5.6文件关闭功能只支持在当前目录进行操作,通过用户给定的文件名在文件索引中搜索到文件的物理文件块ID,找到该文件元素后,将文件当前状态置为关闭。5.7删除文件功能删除文件并不真正清理文件的物理存储内容,只是将文件的有效状态更改为无效开始遍历是否超过512块数?是否存在此文件i_number=I查到512对不起,找不到相应的文件判断用户是否有该权限文件名和目录都设为空对不起,你无权删除此文件是否遍历超过文件块地址恢复初值i节点恢复初值YesNoNoYesYesNoYesNoNo返回5.8创建子目录功能只支持在当前目录创建文件,与创建文件有点类似。Style=0遍历块数超过512存在目录不目录存在,不许建立重名的目录遍历块数i_节点号是否没有分配?I节点的内容进行修改,插入文件的系统文件表里分配空间是否在长度范围之内文件缓冲地址的内容赋予文件的物理地址Style=1NoYes\NoYesNoYes5.9改变当前目录功能开始是否遍历完512?文件的i节点号赋予k是否存在该目录是否为目录名此名赋予当前目录名I是否等于512没有这个目录YesNoYesNoNoYes5.10列出当前目录下的文件,流程图如下:遍历文件块是否超过512开始是否为文件的目录打开文件的属性YesNo四、程序清单#includestdio.h#includestdlib.h#includeconio.h#includestring.h#defineG_Read8//同组用户对文件的读操作权限#defineG_Write4//同组用户对文件的写权限#defineG_Delete2//同组用户对文件的删除权限#defineG_Execute1//对文件有执行的权限,即修改文件权限的权限#defineO_Read128//文件主对文件的读权限#defineO_Write64//文件主对文件的写权限#defineO_Delete32//文件主对文件的删除权限#defineO_Execute16//对文件有执行的权限,即修改文件权限的权限//定义各个用户#defineUser11#defineUser22intcurrentuser;//记录当前用户intaddress_buffer[100];/*文件地址缓冲区*/intstyle=1;/*文件的类型*/charcur_dir[10]=root;/*当前目录*/charbuffer[100];charuser[10]=;structcommand{charcom[10];}cmd[17];structblock{intn;/*空闲的盘块的个数*/intfree[50];/*存放空闲盘块的地址*/inta;/*模拟盘块是否被占用*/}memory[512];//定义存放文件的数据体structfile_block{charp[512];}fileBlock[1536];structblock_super{intn;/*空闲的盘块的个数*/intfree[50];/*存放进入栈中的空闲块*/intstack[50];/*存放下一组空闲盘快的地址*/}super_block;structnode/*i结点信息*/{intfile_style;/*i结点文件类型*/intfile_length;/*i结点文件长度*/intfile_mode;intfile_userid;intfile_groupid;intfile_address[10];/*i结点文件的物理地址*/}i_node[512];structactive_node{structnodefile_node;inti_count;inti_number;}ActiveNode[30];structuser_file_table{intlocation[15];}UserFileTable[2];structsystem_file_table{charfilename[10];intpointer;}SystemFileTable[30];structdir/*目录项信息*/{charfile_name[10];/*文件名*/inti_num;/*文件的结点号*/chardir_name[10];/*文件所在的目录*/}root[512];voidInitUserFileTable(){inti;for(i=0;i15;i++){UserFileTable[0].location[i]=-1;UserFileTable[1].location[i]=-1;}}voidInitSystemFileTable(){inti;for(i=0;i30;i++){strcpy(SystemFileTable[i].filename,);SystemFileTable[i].pointer=-1;}}voidInitActiveNode(){inti;for(i=0;i30;i++){ActiveNode[i].i_count=0;ActiveNode[i].i_number=-1;}}voidInsertAFileIntoSystemFileTable(char*filename,inti_number){inti,j,k;intlocation=-1,t;//检查是否当前用户打开文件表有该记录for(i=0;i15;i++){j=UserFileTable[currentuser-1].location[i];k=SystemFileTable[j].pointer;t=ActiveNode[k].i_number;if(!strcmp(SystemFileTable[j].filename,filename)&&i_number==t)return;if(j==-1)location=i;}if(location==-1){printf(用户打开文件表已满!\n);return;}//检查该当前用户打开表中没有该记录,但系统打开表中有for(i=0;i30;i++){k=SystemFileTable[i].pointer;t=ActiveNode[k].i_number;if(!strcmp(SystemFileTable[j].filename,filename)&&i_number==t){UserFileTable[currentuser-1].location[location]=i;ActiveNode[k].i_count+=1;return;}}//在当前的用户打开