资源描述
高级操作系统实验报告姓 名: 学 号: 专 业: 任 课 教 师: 2014年01 月18 目 录一、课程设计题目和目的1二、课程设计要求1三、程序设计思想1四、文件系统的实现21.数据结构设计22.程序功能图33.实体关系图34.数据流图45.程序流程图5(1) 建立文件:create(文件名,记录长度)6(2) 写文件:write(文件名,开始位置,字符串)7(3) 读文件:read(文件名,开始位置,长度)8(4) 显示文件所有内容 type(文件名)8(5) 删除文件delete(文件名)9(6) 重命名文件ren(文件名,新文件名)10(7) 查询文件属性ask(文件名)11(8) 关闭文件close(文件名)12五、程序运行结果及分析13六、课程设计总结15七、参考文献16八、附录17编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:第31页 共33页一、课程设计题目和目的通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。二、课程设计要求通过组长分工,我主要完成了如下几个功能的操作:1创建文件:从命令中得到文件名,得到该文件的文件长度,建立文件。修改目录表。4读文件:read 文件名 显示开始字节 显示的字节数 ,直接显示所需要的字节数。5写文件:write 文件名 插入的位置 插入的内容6修改属性:修改文件属性 文件名,文件权限,文件长度等。三、程序设计思想阅读操作系统方面的书籍,了解操作系统的文件系统原理。结合分析课程设计要求,确定实体以及它们之间的关系。实体关系有三张表(磁盘空间分配表、文件表、打开文件表)、一个模拟磁盘的数组、命令服务和用户构成。用户负责输入命令。命令服务实现命令的解释、命令检查、命令帮助以及调用相关模块执行相应的命令功能。文件夹打开是则把文件夹名称及其地址压入打开文件夹栈,文件关闭则把文件夹名称及其地址从打开文件夹栈中抛出。文件打开则把文件的名称及其父指针写到文件列表同时置文件打开标志为1,文件关闭则把文件从打开列表中删除,同时置文件打开指针为0,文件读取和写入都要检查文件是否在文件打开列表中,未打开文件不能读写,只读文件不能写,只写文件不能读。文件夹和文件创建,文件夹和文件的创建首先检验目录是否为空,为空则把文件夹或文件连接到该目录下,不为空则把检查目录下是否有同名文件夹或文件,有则提示创建不成功,没有则把文件夹或文件连接到该目录下的最后一个子节点,作为它的兄弟节点。文件夹和文件的删除,文件夹下没有打开的文件或文件没有打开才能删除,否则删除失败,删除文件夹时利用了中序历遍来删除子树。四、文件系统的实现1.数据结构设计通过分析课程设计要求,具体设计出如下数据结构: typedef struct uof /文件属性char filename14; /文件名字int mode; /文件的权限0-readonly;1-writeonly;2-read/writeint length; /文件长度int addr; /物理块号int state; /0-建立,1-建立int readptr; ;通过结构体,将文件名字、文件在磁盘的开始位置、文件长度、文件最大长度、文件类型、创建时间结合在一起。文件类型,本模拟程序使用txt类型。设置一个线性表来存储文件。2.程序功能图 模拟文件系统创建文件删除文件条件读取写入文件查询属性显示内容显示目录重命名文件关闭文件文件系统提供的文件操作有建立文件(create)、删除文件(delete)、条件读取文件(read)、写入文件(write)、查询文件的属性(ask)、显示文件所有内容(type)、重命名文件(ren)、关闭文件(close)。可以通过键盘输入命令来模拟文件的操作。通过exit命令退出程序。3.实体关系图用 户命令服务模拟磁盘磁盘空间分配表文件表打开文件表 命令服务使得用户能够输入命令,在需要时提供命令的帮助。同时能够分析命令,调用相应的命令模块对模拟磁盘、磁盘空间分配表、文件表、打开文件表进行操作。磁盘空间分配表记录模拟磁盘的使用情况。文件表记录文件的信息和在磁盘里的位置等信息。打开文件表记录已打开的文件,对应文件表中的文件信息,和文件表里的文件节点类似,记录了文件在模拟磁盘中的信息。4.程序流程图模拟文件系统提供的文件操作有建立(create),读取(read),显示(type),删除(detele),写入(write),关闭(close),重命名(ren)和查询(ask)。在模拟程序中可从键盘上输入文件操作命令来模拟各用户程序中所调用的各种文件操作,用一个结束命令(exit)停止程序的执行。开始系统格式化Y/N/输入命令命令表中有该命令?分析命令显示:命令帮助无创建删除读取显示重命名写入查询列表关闭退出程序(exit)执行命令执行命令(1) 创建文件:create(文件名,记录长度)模拟文件系统进行“创建文件”的处理流程如下:开始查询文件表文件表中有名字?返回有显示重命申请磁盘空间空间申请成功?显示失败否返回无在磁盘分配表中登记登记:长度=0,最大长度=申请长度,开始位置申请节点位置空闲情况占用在文件表中登记登记:长度=0,最大长度=建立长度,开始位置分配位置文件类型txt,时间当前时间在打开文件表中登记登记:信息和文件表中类似显示创建成功返回(2) 写文件:write(文件名,开始位置,字符串)模拟文件系统进行“建立文件”的处理流程如下:开始查询打开文件表查询文件表在打开文件表里?不在在文件表里?显示无文件返回不在写进模拟磁盘在在读取文件记录write参数合法?合法显示成功返回显示参数非法非法(3) 读文件:read(文件名,开始位置,长度)模拟文件系统进行“读取文件”的处理流程如下:开始查询文件表在打开文件表里?不在在文件表里?显示无文件返回不在在在读取文件记录read参数合法?非法显示参数非法返回根据参数读取模拟磁盘里的记录返回合法五实验程序说明:1.创建文件:2.打开文件:3.写文件:4.修改文件属性:六、课程设计总结通过本次的课程设计,使我能够正确运用操作系统课程中所学的基本理论和知识,加深了对文件系统基本概念的理解,以及磁盘文件系统的文件操作。还有让我感受挺深的是对软件工程方法的应用。设计一个软件,先要做好需求分析,这一点很重要,如果没有分析好需求,到软件设计的最后,发现所做的功能不符合要求,那么一切都得重做,前面所有的努力都付诸东流。在程序设计的开始,由于分析工作做得不够深入和细致,吃了点小苦头。对于这样一个小设计来说,都会吃苦头,要是大工程更是无法想像,有可能会项目失败。以后得加强对软件工程的学习。另外在运用C语言的时候,感觉有点生疏,在组织语言时时而出错,在编程和调试的过程中,经常会出现意想不到的问题,并非每个问题都可以从相关资料中找到解决方法,有些问题是无法预料到的,这就需要通过自己理性的分析得出问题的解决方案。 在设计过程中,查询了不少相关资料,不断的发现问题、提出问题、解决问题。在对自己所编写的源程序段的纠错的过程中,使我更好的理解了操作系统中文件系统的理论知识,同时在编程时用到了模块化的设计思想,这种编程方法可以使我们的编程变的更简单,可以使我们的查错与纠错变的更方便。总的来说通过这次的设计的学习使我学到了很多在平时的学习中学不到的很多东西,通过这次课程设计,使我对操作系统和编程产生兴趣,我想我会在这条路上继续前进下去。我相信,只要不断的严格要求自己,注意培养自己的思维能力,就一定会有更大更辉煌的发展和提高。七、参考文献1美Abraham Silberschatz Peter Baer Galvin Greg Gagne 郑扣根 译.OPERATING SYSTEM CONCEPTSSixth Edition 操作系统概念.高等教育出版社,2004,012(美)Roger S.Pressman 著 梅宏 译.软件工程-实践者的研究方法.机械工业出版社,2002,093蔡启先.C语言程序设计教程(第二版).重庆大学出版社,2003,074朱战立.数据结构.西安电子科技大学出版社,2003,05八、附录1.程序源代码及注释/ 编译工具:Visual c+ 6.0 / / 作者:小楚*smill 、蓝色的天空 / 邮件:qvb20974151 / / 复制、传播请保留作者信息,谢谢! / /#include #include #include #include #include void fileCreate(char *fileName,int fileLenght); /创建文件void fileDel(char *fileName); /删除文件void fileRead(char *fileName,int postion,int lenght);void fileWrite(char *fileName,int position,char *s); /函数声明void fileAsk(char *fileName); /查询文件属性void fileType(char *fileName); /显示文件内容void fileRen(char *fileName,char *newName); /重命名文件void fileDir(); /列出所有文件void fileClose(char *fileName); /关闭一个文件int requestDisk(int *startPosition,int *maxLength); /分配磁盘空间/模拟磁盘空间char disk10000; /磁盘空间管理 struct freeDiskTable int start; /开始位置int length; /占用长度int maxLength; /最大长度int useFlag; /使用标志,1为占用,0为空闲;/文件表struct fileTablechar fileName20; /文件名字int start; /开始位置int length; /文件长度int maxLength; /最大长度 char fileKind8; /文件种类,此默认为txtstruct tm *timeinfo; /文件创建时间;/打开文件表struct openFileTablechar fileName20; /文件名字char fileKind8; /文件类型int start; /文件开始位置int length; /文件长度int maxLength; /最大长度int openCount; /打开文件的进程数struct tm *timeinfo; /文件创建时间;/typedef struct freeDiskTable LinDataType; /定义链表的数据类型#include LinList.h /链表操作集合SLNode *freeDiskTableHead; /定义磁盘分配表链表 头指针#define MaxSize 100 /定义线性表 最大长度typedef struct fileTable SeqDataType; /定义线性表数据类型#include SeqList.h /线性表操作集合SeqList L; /文件表,模拟文件操作嘛,文件数不多,故可以用 线性表,简化操作_struct openFileTable OFT10; /打开文件表数组int OFT_count=0; /打开文件表占用长度void main()struct orderTable /命令表char name8; ;char orderInput30; /存储用户输入的命令字符串char orderName8; /命令名字char fileName20; /命令参数1,是文件名字char parameter26; /命令参数2,是个数字char parameter330; /命令参数3,是字符串或数字struct orderTable u9; /命令表int i=0; int flag=0; /用户输入串 读写位置 标志int flagOrder=-1;/ LinListInitiate(&freeDiskTableHead);/磁盘空间分配键表初始化struct freeDiskTable temp; temp.length=0;temp.maxLength=10000;temp.start=0;temp.useFlag=0;if(!LinListInsert(freeDiskTableHead,0,temp)printf(初始磁盘空闲表失败!);system(pause);exit(0);/文件表初始化SeqListInitiate(&L); /初始化 文件表/for(i=0;i2;i+) for(int j=0;j2;j+)system(color fc);printf(nnnnnnnnn 计 046 何珠举 操作系统课程设计n);for(int k=0;k30000000;k+);system(cls);system(color f3);printf(nnnnnnnnn 计 046 何珠举 操作系统课程设计n);for(k=0;k);fflush(stdin); /清空缓冲区gets(orderInput); /获取用户输入串if(!strcmp(orderInput,exit)exit(0); /当用户输入 exit 退出程序system(cls); /清屏for(i=0;orderInputi!= &orderInputi!=0;i+)/以空格为界 分解用户输入串orderNamei=orderInputi;flag=i;/保存读写指针if(flag6) /命令名长度 小于6printf(输入的命令有误,请重新输入!n);continue ;orderNamei=0;flagOrder=-1; /初始化标志位,flagOrder 指明命令在命令表中的位置for(i=0;i9;i+)if(!strcmp(orderName,ui.name)flagOrder=i; /记录命令的位置,以便访问break;if(flagOrder=-1)printf(你输入的命令有误!请重新输入!n);continue ;/以空格为界,分解字符串,分解出第一个字符串放到fileName中for(i=flag+1;orderInputi!= &orderInputi!=0;i+)fileNamei-flag-1=orderInputi;fileNamei-flag-1=0; /为字符串数组 置一个结束标志/flag=i; /下一个字符串 读写指针if(!strcmp(fileName,?) /显示命令帮助switch(flagOrder)case 0: printf(创建一个文件 格式 create filenamefilelengthn);printf(例如: create a1 1000 ,将创建名为a1,长度为1000字节的文件n);break;case 1:printf(删除一个文件 格式 delete filename n);printf(例如: delete a1,将删除名为a1的文件n);break;case 2: printf(读取一个文件 格式 read filenamepostionlengthn);printf(例如: read a1 8 3,从a1文件第8个字节开始,显示3字节内容n);break;case 3:printf(写一个文件 格式 write fileNamepostionconten n);printf(例始: write a1 15 test,从a1文件第15字节开始写入 test 字符串n);break;case 4:printf(显示文件的属性,格式 ask filenamen); printf(例如 ask a1 ,将显示文件 a1的属性n);break; case 5:printf(显示文件的所有内容,格式 type filenamen);printf(例如 type a1,将显示文件 a1的所有内容n);break;case 6:printf(重命名一个文件,格式 ren oldFileNamenewFileNamen);printf(例如ren a1 b1 ,将a1改名为b1n);break;case 7:printf(显示所有文件,例如 dir,将显示所有文件n);break;case 8:printf(关闭文件,格式 close fileNamen);printf(例如,close a1,将关闭文件a1n);break;default:printf(命令错误);getch();elseswitch(flagOrder)/对相应的命令 进行参数处理case 0:int Temp4=1,10,100,1000;int sum=0;int len=0;for(i=flag+1;orderInputi!= &orderInputi!=0;i+)parameter2i-flag-1=orderInputi;parameter2i-flag-1=0; /为字符串数组 置一个结束标志flag=i; len=strlen(parameter2); /求字符串数组的长度for(i=0;ilen;i+) /把第二个参数 字符串变成整数sum=sum+(int)parameter2len-i-1-48)*Tempi;fileCreate(fileName,sum); /将命令和参数 传给建文件模块执行break;case 1:fileDel(fileName); /删除文件 break;case 2:int Temp4=1,10,100,1000;int sum=0;int len=0;int sum2=0;/for(i=flag+1;orderInputi!= &orderInputi!=0;i+)parameter2i-flag-1=orderInputi;parameter2i-flag-1=0;flag=i; len=strlen(parameter2); /求字符串数组的长度for(i=0;ilen;i+) /把第二个参数 字符串变成整数sum=sum+(int)parameter2len-i-1-48)*Tempi;/for(i=flag+1;orderInputi!= &orderInputi!=0;i+)parameter3i-flag-1=orderInputi; /把第三个参数变成整型parameter3i-flag-1=0;flag=i; len=strlen(parameter3);for(i=0;ilen;i+)sum2=sum2+(int)parameter3len-i-1-48)*Tempi;fileRead(fileName,sum,sum2); /调用读文件模块break;case 3:int Temp4=1,10,100,1000;int sum=0;int len=0;/for(i=flag+1;orderInputi!= &orderInputi!=0;i+)parameter2i-flag-1=orderInputi;parameter2i-flag-1=0;flag=i; len=strlen(parameter2); /求字符串数组的长度for(i=0;ilen;i+) /把第二个参数 字符串变成整数sum=sum+(int)parameter2len-i-1-48)*Tempi;/for(i=flag+1;orderInputi!= &orderInputi!=0;i+)parameter3i-flag-1=orderInputi; /获取第三个参数,为字符串parameter3i-flag-1=0;flag=i; /fileWrite(fileName,sum,parameter3); /调用写文件模块 break;case 4:fileAsk(fileName); /查询文件属性break;case 5:fileType(fileName); /显示文件内容break;case 6:for(i=flag+1;orderInputi!= &orderInputi!=0;i+)parameter2i-flag-1=orderInputi;parameter2i-flag-1=0;flag=i; fileRen(fileName,parameter2);break;case 7:fileDir();break;case 8:fileClose(fileName);break;default:printf(错误!没有可执行的命令);/以上主函数,主函数进行数据结构的定义 分析用户输入的命令。/提供命令帮助。把命令和参数,传递给执行模块/void fileCreate(char *fileName,int fileLength)/没有写到打开文件表int i=0;time_t rawtime;int startPosition=0; /文件开始位置,等磁盘分配函数 返回值int maxLength=fileLength;struct fileTable temp;for(i=0;iL.size;i+)if(!strcmp(fileName,L.listi.fileName) /判断是否重名,如果重名直接返回printf(文件重名,请取别的名字!n);return ; /文件重名,退出创建函数 if(!requestDisk(&startPosition,&maxLength)printf(申请磁盘空间失败!无法建立文件!n);return ; /申请磁盘空间失败,退出创建函数strcpy(temp.fileName,fileName); strcpy(temp.fileKind,txt); /设置文件类型为 txttemp.length=0; /创建的时候,还没写入内容,是空文件,长度设为0temp.maxLength=fileLength; /文件的最大长度temp.start=startPosition; /文件的开始位置time(&rawtime); /获取时间temp.timeinfo=localtime(&rawtime); /把时间写到结构体里去if(!SeqListInsert(&L,L.size,temp) /把文件 插入到文件表printf(插入文件表失败!n);system(pause);exit(0); /把文件插入到 文件表,如果失败,退出程序printf(成功创建文件!nn);printf(=n);printf(文件名 长度 最大长度 类型 开始位置n);/显示刚建立的文件printf(%s ,temp.fileName);printf(%d ,temp.length);printf(%d ,temp.maxLength);printf(%s ,temp.fileKind);printf(%d ,temp.start);printf(n=n);printf(create进程打开了文件%s,关闭请用close命令!nn,fileName);/写到打开文件表strcpy(OFTOFT_count.fileName,temp.fileName);strcpy(OFTOFT_count.fileKind,temp.fileKind);OFTOFT_count.length=temp.length;OFTOFT_count.maxLength=temp.maxLength;OFTOFT_count.start=temp.start;OFTOFT_count.openCount=1;OFTOFT_count.timeinfo=temp.timeinfo;OFT_count+; /打开表 记录的是文件数 /printf(count%d,OFT_count);void fileDel(char *fileName)int i;int flag=0; int k=0; /记录文件在 文件表中的位置SLNode *p; /磁盘空间分配表 指针SeqDataType x; /存储被删除的结点,无特殊意义for(i=0;iOFT_count;i+) /判断是否被别的进程占用,若被占用,打印出错,直接返回 if(!strcmp(fileName,OFTi.fileName)printf(别的进程占用文件!无法删除!);return ;for(i=0;inext!=NULL;p=p-next)if(p-next-data.start=L.listk.start)p-next-data.useFlag=0;printf(成功删除!n);break;SeqListDelete(&L,k,&x);/从文件表中删除void fileRead(char *fileName,int position,int length)int i;int flag=0;int k=0;for(i=0;iOFT_count;i+) /查找文件打开表,如果存在,则不需要再查找文件表if(!strcmp(fileName,OFTi.fileName)k=i;flag=1;OFTi.openCount+;/多个进程打开,计算器加1break;if(flag!=1) /文件不在打开表,找到它,并写到打开表最后for(i=0;iL.size;i+)if(!strcmp(fileName,L.listi.fileName) /找到文件,写到文件打开表strcpy(OFTOFT_count.fileName,L.listi.fileName);strcpy(OFTOFT_count.fileKind,L.listi.fileKind);OFTOFT_count.length=L.listi.length;OFTOFT_count.maxLength=L.listi.maxLength;OFTOFT_count.start=L.listi.start;OFTOFT_count.timeinfo=L.listi.timeinfo;OFTOFT_count.openCount+;k=OFT_count;/OFT_count=1;/初次打开,赋值为1flag=1; /标志在打开文件表里if(flag=1)if(positionOFTk.length)printf(读取参数错误,请检查参数!n);return ;for(i=0;ilength;i+)printf(%c,diskOFTk.start+position+i-1); /读取内容printf(nread进程打开了文件%s,关闭请用close命令!nn,fileName);void fileWrite(char *fileName,int position,char *s)/找到文件,写到打开表,根据打开表操作int i=0;int len=0; /计算写入字串长度,跟原来长度相加,如果超过最大长度,就失败int k=0; /如果在 打开表里打到记录,则记录位置int flag=0; /如果flag=1,说明在打开表里找到了,不用在文件表里找了len=strlen(s);for(i=0;iOFT_count;i+)if(!strcmp(fileName,OFTi.fileName)k=i;flag=1;OFTi.openCount+;/多个进程打开,计算器加1break;if(flag!=1) /文件不在打开表,找到它,并写到打开表最后for(i=0;iOFTk.maxLength)printf(超过文件最大长度,写入失败!n);return ;else if(positionOFTk.length)printf(插入位置非法!请检查参数n);return ;elseint j=0;for(i=OFTk.length-1;i=OFTk.start+position;i-)diski+len=diski; /给插入的字符串 空出位置for(i=OFTk.start+position;iOFTk.start+position+len;i+,j+)diski=sj; /写进磁盘for(i=0;iL.size;i+) /改变文件长度if(!strcmp(fileName,L.listi.fileName)L.listi.length=L.listi.length+len; /设置文件长度break; OFTk.length=OFTk.length+len; /同时更新打开文件表中文件的长度printf(成功写入!n);printf(write进程打开了文件%s,关闭请用close命令!nn,fileName);elseprintf(无此文件,请输入正确的文件名!);void fileAsk(char *fileName)int i;int flag=0;for(i=0;iOFT_count;i+) /如果在打开表里 找到文件,则不用再找文件表if(!strcmp(fileName,OFTi.fileName)printf(文件名:%sn,OFTi.fileName);printf(类型:%sn,OFTi.fileKind);printf(长度:%dn,OFTi.length);printf(打开进程数:%dn,OFTi.openCount);printf(创建时间:%sn,asctime(OFTi.timeinfo);flag=1;break;if(flag!=1)for(i=0;iL.size;i+) /从文件表里查找文件if(!strcmp(fileName,L.listi.fileName)printf(文件名:%sn,L.listi.fileName);printf(类型:%sn,L.listi.fileKind);printf(长度:
展开阅读全文