资源描述
中北大学
操作系统课程设计
说 明 书
学 院、系:
软件学院
专 业:
软件工程
学 生 姓 名:
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. 详细设计
主要数据结构:
#define MEM_D_SIZE 1024*1024 //总磁盘空间为1M
#define DISKSIZE 1024 ﻩ //磁盘块得大小1K
#define DISK_NUM 1024 ﻩ //磁盘块数目1K
#define FATSIZE DISK_NUM*sizeof(struct fatitem)ﻩ//FAT表大小
#define ROOT_DISK_NO FATSIZE/DISKSIZE+1 ﻩ //根目录起始盘块号
#define ROOT_DISK_SIZE sizeof(struct direct)ﻩﻩ//根目录大小
#define DIR_MAXSIZE 1024 //路径最大长度为1KB
#define MSD 5ﻩ ﻩﻩ //最大子目录数5
#define MOFN 5 ﻩ ﻩﻩ//最大文件深度为5
#define MAX_WRITE 1024*128 ﻩ//最大写入文字长度128KB
struct fatitem /* size 8*/
{
int item; /*存放文件下一个磁盘得指针*/
char em_disk; /*磁盘块就就是否空闲标志位 0 空闲*/
};
struct direct
{
ﻩ/*-----文件控制快信息-----*/
struct FCB
{
ﻩchar name[9]; /*文件/目录名 8位*/
char property; /*属性 1位目录 0位普通文件*/
ﻩ int size; /*文件/目录字节数、盘块数)*/
ﻩﻩint firstdisk; /*文件/目录 起始盘块号*/
ﻩ int next; /*子目录起始盘块号*/
ﻩﻩint sign; /*1就就是根目录 0不就就是根目录*/
ﻩ}directitem[MSD+2];
};
struct opentable
{
ﻩstruct openttableitem
ﻩ{
ﻩﻩchar name[9]; /*文件名*/
ﻩint firstdisk; /*起始盘块号*/
ﻩint size; /*文件得大小*/
ﻩ}openitem[MOFN];
ﻩint cur_size; /*当前打文件得数目*/
};
管理文件得主要代码:
int create(char *name)
{
int i,j;
if(strlen(name)>8) /*文件名大于 8位*/
ﻩreturn(-1);
for(j=2;j<MSD+2;j++) /*检查创建文件就就是否与已存在得文件重名*/
{
ﻩ if(!strcmp(cur_dir->directitem[j]、name,name))
ﻩ break;
}
if(j<MSD+2) /*文件已经存在*/
ﻩ return(-4);
for(i=2;i<MSD+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<DISK_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);
return 0;
}
int open(char *name)
{
int i, j;
for(i=2;i<MSD+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<MOFN;j++)
{
ﻩﻩif(!strcmp(u_opentable、openitem[j]、name,name))
ﻩﻩﻩbreak;
}
if(j<MOFN) /*文件已经打开*/
return(-2);
if(u_opentable、cur_size>=MOFN) /*文件打开太多*/
ﻩreturn(-3);
/*--------查找一个空闲用户打开表项-----------------------*/
for(j=0;j<MOFN;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);
}
int close(char *name)
{
int i;
for(i=0;i<MOFN;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--;
return 0;
}
int write(int fd, char *buf, int len)
{
char *first;
ﻩint item, i, j, k;
int ilen1, ilen2, modlen, temp;
ﻩ/*----------用 $ 字符作为空格 # 字符作为换行符-----------------------*/
ﻩchar Space = 32;
ﻩchar Endter= '\n';
ﻩfor(i=0;i<len;i++)
{
ﻩ if(buf[i] == '$')
ﻩ ﻩbuf[i] = Space;
else if(buf[i] == '#')
ﻩﻩﻩbuf[i] = Endter;
}
/*----------读取用户打开表对应表项第一个盘块号-----------------------*/
item = u_opentable、openitem[fd]、firstdisk;
ﻩ/*-------------找到当前目录所对应表项得序号-------------------------*/
for(i=2;i<MSD+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<ilen2;j++)
ﻩ{
ﻩ ﻩfor(i=ROOT_DISK_NO+1;i<DISK_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;k<len-(DISKSIZE-u_opentable、openitem[fd]、size%DISKSIZE)-j*DISKSIZE;k++)
ﻩ ﻩﻩﻩfirst[k] = buf[k];
ﻩﻩ}
ﻩﻩ else/*-如果不就就是要最后分配得一块--*/
ﻩﻩﻩ{
ﻩﻩfor(k=0;k<DISKSIZE;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;
ﻩ}
return 0;
}
int read(int fd, char *buf)
{
int len = u_opentable、openitem[fd]、size;
ﻩchar *first;
int i, j, item;
ﻩint ilen1, 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<ilen1;i++)
{
if(i==ilen1-1) /*--如果在最后一个磁盘块-*/
{
ﻩfor(j=0;j<len-i*DISKSIZE;j++)
ﻩﻩbuf[i*DISKSIZE+j] = first[j];
ﻩﻩ}
ﻩﻩelse /*--不在最后一块磁盘块-*/
ﻩ {
ﻩ for(j=0;j<len-i*DISKSIZE;j++)
ﻩbuf[i*DISKSIZE+j] = first[j];
ﻩ item = fat[item]、item; /*-查找下一盘块-*/
ﻩ first = fdisk+item*DISKSIZE;
ﻩ}
ﻩ}
ﻩreturn 0; ﻩ
}
int del(char *name)
{
int i,cur_item,item,temp;
ﻩfor(i=2;i<MSD+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<MOFN;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;
return 0;
}
主函数:
int main()
{
ﻩFILE *fp;
char ch;
ﻩchar a[100];
ﻩchar code[11][10];
ﻩchar name[10];
ﻩint i,flag,r_size;
ﻩchar *contect;
contect = (char *)malloc(MAX_WRITE*sizeof(char));
ﻩif((fp=fopen("disk、dat","rb"))==NULL)
ﻩ{
ﻩﻩprintf("You have not format,Do you want format?(y/n)");
ﻩscanf("%c",&ch);
ﻩ if(ch=='y')
ﻩﻩ{
ﻩﻩinitfile();
ﻩﻩ printf("Successfully format! \n");
ﻩﻩ}
ﻩelse
{
ﻩﻩﻩreturn 0;
}
}
ﻩ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)
ﻩﻩ{
ﻩﻩcase 0: //退出文件系统
ﻩﻩﻩfree(contect);
ﻩhalt();
ﻩ ﻩreturn 0;
ﻩ case 1: //创建文件
ﻩﻩscanf("%s",name);
ﻩflag = create(name);
ﻩﻩﻩif(flag==-1)
ﻩﻩﻩ{
ﻩ printf("Error: \n The length is too long !\n");
ﻩﻩﻩ}
ﻩﻩelse if(flag==-2)
ﻩﻩ{
ﻩﻩﻩﻩprintf("Error: \n The direct item is already full !\n");
ﻩ ﻩ}
ﻩﻩelse if(flag==-3)
ﻩﻩﻩ{
ﻩ ﻩprintf("Error: \n The number of open too much !\n");
}
ﻩﻩelse if(flag==-4)
ﻩ {
ﻩﻩ printf("Error: \n The name is already in the direct !\n");
ﻩ }
ﻩﻩ else if(flag==-5)
ﻩﻩ {
ﻩ ﻩﻩprintf("Error: \n The disk space is full!\n");
ﻩ}
ﻩﻩelse
ﻩ ﻩ{
ﻩ printf("Successfully create a file! \n");
ﻩ ﻩ}
ﻩ show();
ﻩﻩbreak;
case 2://打开文件
ﻩﻩscanf("%s",name);
ﻩfd = open(name);
ﻩﻩﻩif(fd == -1)
ﻩﻩ {
ﻩ ﻩﻩprintf("Error: \n The open exit! \n");
ﻩ }
ﻩﻩﻩelse if(fd == -2)
ﻩﻩ {
ﻩﻩ printf("Error: \n The already opened! \n");
ﻩ }
ﻩ else if(fd == -3)
ﻩ {
ﻩ ﻩprintf("Error: \n The number of open too much! \n");
ﻩ }
ﻩ ﻩelse if(fd == -4)
ﻩﻩ {
ﻩ printf("Error: \n It is a direct,can not open for read or write! \n");
ﻩ}
ﻩﻩﻩelse
ﻩ ﻩ{
ﻩ ﻩprintf("Successfully opened! \n");
ﻩﻩ }
ﻩ show();
ﻩ break;
case 3://关闭文件
ﻩﻩscanf("%s",name);
flag = close(name);
ﻩ if(flag == -1)
ﻩ {
ﻩ printf("Error:\n The not opened ! \n");
ﻩﻩ }
ﻩﻩelse
ﻩ{
ﻩ printf("Successfully closed! \n");
ﻩ }
ﻩ ﻩshow();
ﻩ break;
case 4://写文件
ﻩ if(fd ==-1)
ﻩ {
ﻩﻩﻩ printf("Error:\n The not opened ! \n");
ﻩ }
ﻩﻩ else
ﻩﻩ{
ﻩ printf("Please input the :");
ﻩﻩ scanf("%s",contect);
ﻩ ﻩﻩflag=write(fd,contect,strlen(contect));
ﻩ if(flag == 0)
ﻩ{
ﻩ ﻩprintf("Successfully write! \n");
ﻩ}
ﻩ else
ﻩ ﻩﻩ{
ﻩﻩ ﻩﻩprintf("Error:\n The disk size is not enough! \n");
ﻩ ﻩ }
ﻩ}
ﻩﻩshow();
ﻩﻩbreak;
ﻩﻩcase 5://读文件
if(fd ==-1)
ﻩ ﻩ{
ﻩ printf("Error:\n The not opened ! \n");
ﻩ ﻩ}
ﻩﻩ else
ﻩ{
ﻩﻩﻩ flag = read(fd,contect);
ﻩﻩ if(flag == 0)
ﻩ ﻩ{
ﻩﻩ for(i=0;i<u_opentable、openitem[fd]、size;i++)
ﻩﻩﻩ{
ﻩ printf("%c",contect[i]);
ﻩ ﻩ}
ﻩﻩﻩ ﻩprintf("\t\n");
ﻩ ﻩ}
ﻩ }
ﻩﻩﻩshow();
break;
ﻩﻩcase 6://删除文件
ﻩ scanf("%s",name);
ﻩﻩ flag = del(name);
ﻩif(flag == -1)
ﻩ ﻩ{
ﻩ ﻩ printf("Error:\n The exit! \n");
ﻩﻩﻩ}
ﻩelse if(flag == -2)
ﻩﻩ {
ﻩﻩﻩﻩprintf("Error:\n The opened,please first close it ! \n");
ﻩﻩ}
ﻩelse if(flag == -3)
ﻩﻩ {
printf("Error:\n The delete is not file ! \n");
ﻩ ﻩ}
ﻩ else
ﻩ{
ﻩ ﻩprintf("Successfully delete! \n");
ﻩﻩ}
ﻩ ﻩshow();
break;
}
}
}
程序运行截图:
4. 心得体会
在设计得过程中,我查询了不少相关资料,不断地发现问题、提出问题、解决问题。用C做程序开发语言,让我重新认识了C得基础,在新语言不断出现并发展迅速得今天,重新体会到C得基础性、重要性,以及面对过程,面对函数式得编程方式。
在对自己所编写得源程序段得纠错得过程中,使我更好得理解了操作系统中文件系统得理论知识,同时在编程时用到了模块化得设计思想,这种编程方法可以使我们得编程更简单,可以使我们得查错与纠错变得更加方便。
总得来说通过这次得设计学习使我学到了很多在平时得学习中学不到得很多东西,对操作系统有了更深一层得了解,同时也提高了C语言得能力,由于时间以及个人知识得问题,因此有很多得地方还需要改进。在以后得学习中还要更加努力。
展开阅读全文