模拟文件系统的设计和实现.docx
- 文档编号:28909117
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:24
- 大小:67.21KB
模拟文件系统的设计和实现.docx
《模拟文件系统的设计和实现.docx》由会员分享,可在线阅读,更多相关《模拟文件系统的设计和实现.docx(24页珍藏版)》请在冰豆网上搜索。
模拟文件系统的设计和实现
中北大学
操作系统课程设计
说明书
学院、系:
软件学院
专业:
软件工程
学生姓名:
xxx
学号:
xxx
设计题目:
模拟文件系统的设计与实现
起迄日期:
2015年12月28日-2016年1月8日
指导教师:
xxx
2016年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//最大写入文字长度128KB
structfatitem/*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;j { if(! strcmp(cur_dir->directitem[j].name,name)) break; } if(j return(-4); for(i=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;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;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;j { if(! strcmp(u_opentable.openitem[j].name,name)) break; } if(j return(-2); if(u_opentable.cur_size>=MOFN)/*文件打开太多*/ return(-3); /*--------查找一个空闲用户打开表项-----------------------*/ for(j=0;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;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;i { if(buf[i]=='$') buf[i]=Space; elseif(buf[i]=='#') buf[i]=Endter; } /*----------读取用户打开表对应表项第一个盘块号-----------------------*/ item=u_opentable.openitem[fd].firstdisk; /*-------------找到当前目录所对应表项的序号-------------------------*/ for(i=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%DISKSIZE>len) { 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(modlen>0) ilen2=ilen2+1;/*--还需要多少块磁盘块-*/ for(j=0;j { for(i=ROOT_DISK_NO+1;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;k first[k]=buf[k]; } else/*-如果不是要最后分配的一块--*/ { for(k=0;k first[k]=buf[k]; } fat[item].item=i;/*--找到一块后将它的序号存放在上一块的指针中-*/ fat[i].em_disk='1';/*--置找到的磁盘快的空闲标志位为已分配-*/ fat[i].item=-1;/*--它的指针为-1(即没有下一块)-*/ } /*--修改长度-*/ u_opentable.openitem[fd].size=u_opentable.openitem[fd].size+len; cur_dir->directitem[temp].size=cur_dir->directitem[temp].size+len; } return0; } intread(intfd,char*buf) { intlen=u_opentable.openitem[fd].size; char*first; inti,j,item; intilen1,modlen; item=u_opentable.openitem[fd].firstdisk; ilen1=len/DISKSIZE; modlen=len%DISKSIZE; if(modlen! =0) ilen1=ilen1+1;/*--计算文件所占磁盘的块数-*/ first=fdisk+item*DISKSIZE;/*--计算文件的起始位置-*/ for(i=0;i { if(i==ilen1-1)/*--如果在最后一个磁盘块-*/ { for(j=0;j buf[i*DISKSIZE+j]=first[j]; } else/*--不在最后一块磁盘块-*/ { for(j=0;j buf[i*DISKSIZE+j]=first[j]; item=fat[item].item;/*-查找下一盘块-*/ first=fdisk+item*DISKSIZE; } } return0; } intdel(char*name) { inti,cur_item,item,temp; for(i=2;i { if(! strcmp(cur_dir->directitem[i].name,name)) break; } cur_item=i;/*--用来保存目录项的序号,供释放目录中-*/ if(i>=MSD+2)/*--如果不在当前目录中-*/ return(-1); if(cur_dir->directitem[cur_item].property! ='0')/*--如果删除的(不)是目录-*/ return(-3); for(i=0;i { if(! strcmp(u_opentable.openitem[i].name,name)) return(-2); } item=cur_dir->directitem[cur_item].firstdisk;/*--该文件的起始盘块号-*/ while(item! =-1)/*--释放空间,将FAT表对应项进行修改-*/ { temp=fat[item].item; fat[item].item=-1; fat[item].em_disk='0'; item=temp; } /*-----------------释放目录项-----------------------*/ cur_dir->directitem[cur_item].sign=0; cur_dir->directitem[cur_item].firstdisk=-1; strcpy(u_opentable.openitem[cur_item].name,""); cur_dir->directitem[cur_item].next=-1; cur_dir->directitem[cur_item].property='0'; cur_dir->directitem[cur_item].size=0; return0; } 主函数: intmain() { FILE*fp; charch; chara[100]; charcode[11][10]; charname[10]; inti,flag,r_size; char*contect; contect=(char*)malloc(MAX_WRITE*sizeof(char)); if((fp=fopen("disk.dat","rb"))==NULL) { printf("Youhavenotformat,Doyouwantformat? (y/n)"); scanf("%c",&ch); if(ch=='y') { initfile(); printf("Successfullyformat! \n"); } else { return0; } } enter(); print(); show(); strcpy(code[0],"exit"); strcpy(code[1],"create"); strcpy(code[2],"open"); strcpy(code[3],"close"); strcpy(code[4],"write"); strcpy(code[5],"read"); strcpy(code[6],"del"); strcpy(code[7],"mkdir"); strcpy(code[8],"rmdir"); strcpy(code[9],"dir"); strcpy(code[10],"cd"); while (1) { scanf("%s",a); for(i=0;i<11;i++) { if(! strcmp(code[i],a)) break; } switch(i) { case0: //退出文件系统 free(contect); halt(); return0; case1: //创建文件 scanf("%s",name); flag=create(name); if(flag==-1) { printf("Error: \nThelengthistoolong! \n"); } elseif(flag==-2) { printf("Error: \nThedirectitemisalreadyfull! \n"); } elseif(flag==-3) { printf("Error: \nThenumberofopenfileistoomuch! \n"); } elseif(flag==-4) { printf("Error: \nThenameisalreadyinthedirect! \n"); } elseif(flag==-5) { printf("Error: \nThediskspaceisfull! \n"); } else { printf("Successfullycreateafile! \n"); } show(); break; case2: //打开文件 scanf("%s",name); fd=open(name); i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 模拟 文件系统 设计 实现