中北大学操作系统课程设计说明书学院、系:软件学院专业:软件工程学生姓名:xxx学号:xxx设计题目:模拟文件系统的设计与实现起迄日期:2015年12月28日-2016年1月8日指导教师:xxx2016年1月8日1需求分析通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识,加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力;掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,并了解操作系统的发展动向和趋势。模拟二级文件管理系统的课程设计目的是通过研究Linux的文件系统结构,模拟设计一个简单的二级文件系统,第一级为主目录文件,第二级为用户文件。2总体设计结合数据结构、程序设计、计算机原理等课程的知识,设计一个二级文件系统,进一步理解操作系统。文件的创建:create文件关闭:close文件的打开:open文件的读:read文件的写:write文件关闭:close删除文件:delete创建子目录:mkdir删除子目录:rmdir列出文件目录:dir退出:exit系统执行流程图开始选择操作创建文件删除文件读文件写文件创建文件夹删除文件夹删除子目录显示当前子目录创建子目录更改目录退出3.详细设计主要数据结构:#defineMEM_D_SIZE1024*1024//总磁盘空间为1M#defineDISKSIZE1024//磁盘块的大小1K#defineDISK_NUM1024//磁盘块数目1K#defineFATSIZEDISK_NUM*sizeof(structfatitem)//FAT表大小#defineROOT_DISK_NOFATSIZE/DISKSIZE+1//根目录起始盘块号#defineROOT_DISK_SIZEsizeof(structdirect)//根目录大小#defineDIR_MAXSIZE1024//路径最大长度为1KB#defineMSD5//最大子目录数5#defineMOFN5//最大文件深度为5#defineMAX_WRITE1024*128//最大写入文字长度128KBstructfatitem/*size8*/{intitem;/*存放文件下一个磁盘的指针*/charem_disk;/*磁盘块是否空闲标志位0空闲*/};structdirect{/*-----文件控制快信息-----*/structFCB{charname[9];/*文件/目录名8位*/charproperty;/*属性1位目录0位普通文件*/intsize;/*文件/目录字节数、盘块数)*/退出intfirstdisk;/*文件/目录起始盘块号*/intnext;/*子目录起始盘块号*/intsign;/*1是根目录0不是根目录*/}directitem[MSD+2];};structopentable{structopenttableitem{charname[9];/*文件名*/intfirstdisk;/*起始盘块号*/intsize;/*文件的大小*/}openitem[MOFN];intcur_size;/*当前打文件的数目*/};管理文件的主要代码:intcreate(char*name){inti,j;if(strlen(name)8)/*文件名大于8位*/return(-1);for(j=2;jMSD+2;j++)/*检查创建文件是否与已存在的文件重名*/{if(!strcmp(cur_dir-directitem[j].name,name))break;}if(jMSD+2)/*文件已经存在*/return(-4);for(i=2;iMSD+2;i++)/*找到第一个空闲子目录*/{if(cur_dir-directitem[i].firstdisk==-1)break;}if(i=MSD+2)/*无空目录项*/return(-2);if(u_opentable.cur_size=MOFN)/*打开文件太多*/return(-3);for(j=ROOT_DISK_NO+1;jDISK_NUM;j++)/*找到空闲盘块j后退出*/{if(fat[j].em_disk=='0')break;}if(j=DISK_NUM)return(-5);fat[j].em_disk='1';/*将空闲块置为已经分配*//*-----------填写目录项-----------------*/strcpy(cur_dir-directitem[i].name,name);cur_dir-directitem[i].firstdisk=j;cur_dir-directitem[i].size=0;cur_dir-directitem[i].next=j;cur_dir-directitem[i].property='0';/*---------------------------------*/fd=open(name);return0;}intopen(char*name){inti,j;for(i=2;iMSD+2;i++)/*文件是否存在*/{if(!strcmp(cur_dir-directitem[i].name,name))break;}if(i=MSD+2)return(-1);/*--------是文件还是目录-----------------------*/if(cur_dir-directitem[i].property=='1')return(-4);/*--------文件是否打开-----------------------*/for(j=0;jMOFN;j++){if(!strcmp(u_opentable.openitem[j].name,name))break;}if(jMOFN)/*文件已经打开*/return(-2);if(u_opentable.cur_size=MOFN)/*文件打开太多*/return(-3);/*--------查找一个空闲用户打开表项-----------------------*/for(j=0;jMOFN;j++){if(u_opentable.openitem[j].firstdisk==-1)break;}/*--------------填写表项的相关信息------------------------*/u_opentable.openitem[j].firstdisk=cur_dir-directitem[i].firstdisk;strcpy(u_opentable.openitem[j].name,name);u_opentable.openitem[j].size=cur_dir-directitem[i].size;u_opentable.cur_size++;/*----------返回用户打开表表项的序号--------------------------*/return(j);}intclose(char*name){inti;for(i=0;iMOFN;i++){if(!strcmp(u_opentable.openitem[i].name,name))break;}if(i=MOFN)return(-1);/*-----------清空该文件的用户打开表项的内容---------------------*/strcpy(u_opentable.openitem[i].name,);u_opentable.openitem[i].firstdisk=-1;u_opentable.openitem[i].size=0;u_opentable.cur_size--;return0;}intwrite(intfd,char*buf,intlen){char*first;intitem,i,j,k;intilen1,ilen2,modlen,temp;/*----------用$字符作为空格#字符作为换行符-----------------------*/charSpace=32;charEndter='\n';for(i=0;ilen;i++){if(buf[i]=='$')buf[i]=Space;elseif(buf[i]=='#')buf[i]=Endter;}/*----------读取用户打开表对应表项第一个盘块号-----------------------*/item=u_opentable.openitem[fd].firstdisk;/*-------------找到当前目录所对应表项的序号-------------------------*/for(i=2;iMSD+2;i++){if(cur_dir-directitem[i].firstdisk==item)break;}temp=i;/*-存放当前目录项的下标-*//*------找到的item是该文件的最后一块磁盘块-------------------*/while(fat[item].item!=-1){item=fat[item].item;/*-查找该文件的下一盘块--*/}/*-----计算出该文件的最末地址-------*/first=fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE;/*-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------*/if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZElen){strcpy(first,buf);u_opentable.openitem[fd].size=u_opentable.openitem[fd].size+len;cur_dir-directitem[temp].size=cur_dir-directitem[temp].size+len;}else{for(i=0;i(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++){/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/first[i]=buf[i];}/*-----计算分配完最后一块磁盘的剩余空间(字节)还剩下多少字节未存储-------*/ilen1=len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);ilen2=ilen1/DISKSIZE;modlen=ilen1%DISKSIZE;if(modlen0)ilen2=ilen2+1;/*--还需要多少块磁盘块-*/for(j=0;jilen2;j++){for(i=ROOT_DISK_NO+1;iDISK_NUM;i++)/*寻找空闲磁盘块*/{if(fat[i].em_disk=='0')break;}if(i=DISK_NUM)/*--如果磁盘块已经分配完了-*/return(-1);first=fdisk+i*DISKSIZE;/*--找到的那块空闲磁盘块的起始地址-*/if(j==ilen2-1)/*--如果是最后要分配的一块-*/{for(k=0;klen-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)-j*DISKSIZE;k++)first[k]=buf[k];}else/*-如果不是要最后分配的一块--*/{for(k=0;kDISKSIZE;k++)first[k]=buf[k];}fat[item].item=i;/*--找到一块后将它的序号存放在上一块的指针中-*/fat[i].em_disk='1';/*--置找到的磁盘快的空闲标志位为已分配-*/fat[i].item=-1;/