操作系统文件系统的设计与实现课程设计.doc
课程设计题 目:文件系统的设计与实现 学 院:信息工程学院系 别:计算机系 专 业:计算机科学与技术 2011年12月30日内蒙古工业大学课程设计任务书学院(系):信息学院计算机系 课程名称:操作系统课程设计 指导教师(签名): 专业班级: 计算机092 学生姓名: 学号: 200920201039 一、课程设计题目文件系统的设计与实现二、课程设计的目的通过设计一个小型文件系统,进一步掌握文件管理的方法和技术,使学生初步具有研究、设计、编制和调试操作系统模块的能力。 三、课程设计的主要内容和要求(包括原始数据、技术参数、设计要求、工作量要求等) 原始数据:文件目录项结构体,盘块结构体。 技术参数:Windows XP系统,VC+6.0开发工具。设计要求: 1 设计基于位示图的文件连续分配算法;2 设计显示文件目录、建立文件、显示文件内容、复制和删除文件算法;3 画出以上算法流程图;4 编程实现算法功能;5编写课程设计说明书。 工作量要求:完成以上设计要求中的所有算法功能。四、工作进度安排 周一:布置、讲解题目,收集资料;周二:系统分析,算法设计;周三:编制、调试程序;周四:测试系统,形成设计结论,编写课设报告;周五:系统及材料验收,课设答辩。五、主要参考文献1 张尧学编计算机操作系统教程(第三版)习题解答与实验指导北京:清华大学出版社,20062 汤子瀛主编计算机操作系统(第三版)西安:西安电子科技大学出版社,2001 3 张坤等编操作系统实验教程北京:清华大学出版社,2008审核批准意见系(教研室)主任(签字) 目录第一章设计内容111 设计目的112 设计要求113 程序设计思想1第二章 数据结构、算法和算法流程图221 数据结构222 程序功能图323 程序流程图3第三章 程序运行结果及分析731 程序运行结果732 程序分析8第四章 心得体会9参考文献10附录 程序清单11第一章 设计内容11 设计目的通过设计一个小型文件系统,进一步掌握文件管理的方法和技术,使学生初步具有研究、设计、编制和调试操作系统模块的能力。12 设计要求(1) 问题描述在任一OS下,建立一个大文件,把它假想成一张盘,在其中实现一个简单的小型文件系统。(2) 基本要求该文件系统没有子目录机制,文件连续分配,不考虑换“盘”和分区。做一个简单的操作界面,提供五条简单的命令:dir、mkfile、type、copy、delfile,分别用于显示文件目录、建立文件、显示文件内容、复制和删除一个文件。13 程序设计思想阅读操作系统方面的书籍,了解操作系统的文件系统原理。结合分析课程设计要求,确定实体以及它们之间的关系。实体关系有三张表(磁盘空间分配表、文件表、打开文件表)、一个模拟磁盘的数组、命令服务和用户构成。用户负责输入命令。命令服务实现命令的解释、命令检查、命令帮助以及调用相关模块执行相应的命令功能。建立一个系统文件(模拟盘),并对此进行盘块的划分,第一个盘块存放文件目录,第二盘块存放盘块位示图,自第三个盘块开始存放各具体文件的内容,文件目录存放文件的名字,文件的扩展名,开始盘块号,所占用的盘块数目,文件的大小;盘块位示图用来标记盘块是否被占用。构造这些实体的关系图,数据流图、程序流程图来进行具体的设计。第二章 数据结构、算法和算法流程图21 数据结构数据结构说明:本程序所运用的主要有两个数据结构,分别如下:文件目录结构: struct filename /文件目录项结构体 char name9; /文件名 char ext4; /扩展名 int i; /文件所占用磁盘块的第一个磁盘块号 int Amount; /文件所占用磁盘块的块数 long int size; /文件大小;盘块结构:struct empty /盘块结构体 int map100; /盘块位示图 int filenum; /文件数量; 22 程序功能图模拟文件系统显示内容显示目录创建文件复制文件删除文件图2.1重命名文件系统提供的文件操作有建立文件(mkfile)、复制文件(copy)、显示文件所有内容(type)、删除文件(delfile)。可以通过键盘输入命令来模拟文件的操作。23 程序流程图(1)主程序流程图:开始初始化盘块输入命令分析命令有无该命令?显示错误信息创建文件显示目录显示内容复制文件删除文件有无执行命令结束图2.2(2)初始化模块流程图:图2.3(3)写入磁盘流程图:图2.4(4)显示目录流程图:图2.5(5)显示文件流程图:图2.6(6)删除文件流程图:图2.7(7)复制文件流程图:图2.8(8)创建文件流程图:图2.9第三章 程序运行结果及分析31 程序运行结果(1)程序主界面图3.1(2)创建一个文件,输入“3”显示“输入文件内容,按 键保存且退出!”图3.2(3)往文件里写内容:Hello World!显示文件长度,并要求给文件命名,命名后保存返回主界面图3.3(4)读取刚才写入的文件,结果正确图3.4(5)删除刚写入的文件,测试成功图3.532 程序分析本程序使用一个Windows下的文件来模拟一个磁盘,向磁盘中装入文件并进行相关操作。采用了以空间换时间的算法,文件的大小在系统中是固定的,虽然会浪费一些空间,但文件的存取速率会加快。第四章 心得体会操作系统课程设计是本课程重要的实践教学环节。课程设计的目的,一方面使学生更透彻地理解操作系统的基本概念和原理,使之由抽象到具体;另一方面,通过课程设计加强学生的实验手段与实践技能,培养学生独立分析问题、解决问题、应用知识的能力和创新精神。与本课程的实验教学相比,课程设计独立设课,具有更多的学时,给学生更多自行设计、自主实验的机会,充分放手让学生真正培养学生的实践动手能力,全面提高学生的综合素质。在设计的过程中遇到问题,可以说得是困难重重,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,不过设计终于顺利完成了,在设计中遇到了很多编程问题,最后在老师的辛勤指导下,终于游逆而解。同时,在老师的身上我学得到很多实用的知识,再次我表示感谢!同时,对给过我们帮助的所有同学和各位指导老师再次表示忠心的感谢! 在设计过程中,查询了不少相关资料,不断的发现问题、提出问题、解决问题。在对自己所编写的源程序段的纠错的过程中,使我更好的理解了操作系统中文件系统的理论知识,同时在编程时用到了模块化的设计思想,这种编程方法可以使我们的编程变的更简单,可以使我们的查错与纠错变的更方便。总的来说通过这次的设计的学习使我学到了很多在平时的学习中学不到的很多东西,通过这次课程设计,使我对操作系统和编程产生兴趣,我想我会在这条路上继续前进下去。我相信,只要不断的严格要求自己,注意培养自己的思维能力,就一定会有更大更辉煌的发展和提高。参考文献1. 教材1 张尧学主编计算机操作系统教程(第三版)北京:清华大学出版社,20062. 主要参考书 1 张尧学编计算机操作系统教程(第三版)习题解答与实验指导北京:清华大学出版社,20062 汤子瀛主编计算机操作系统(第三版)西安:西安电子科技大学出版社,2001 3 张坤等编操作系统实验教程北京:清华大学出版社,20084 张丽芬等编操作系统实验教程北京:清华大学出版社,20065 Andrew S.Tanenbaum. Modern Operating Systems, Second Edition.Englewood Cliffs,N.J,Prentice Hall, 20016 屠祁等编.操作系统基础(第三版)北京:清华大学出版社,20007 冯耀霖等编.操作系统.西安:西安电子科技大学出版社,20018 左万历计算机操作系统教程(第二版)北京:高等教育出版社,2004附录 程序清单#include "iostream.h"#include "string"#include "stdio.h"extern "C" void exit(int);struct filename /文件目录项结构体 char name12; /文件名 char ext8; /扩展名/扩展名较小设为10 int i; /文件所占用磁盘块的第一个磁盘块号 int Amount; /文件所占用磁盘块的块数 long int size; /文件大小file20;int num; struct empty /盘块结构体 int map20; /盘块位示图 int filenum; /文件数量emptytable; /模块说明:void SystemInit() /模拟磁盘文件初始化函数 for(int i=2;i<19;i+) /初始化存放位示图的盘块 emptytable.mapi=0; emptytable.map0=1; emptytable.map1=1; emptytable.filenum=0;FILE *fp;if(fp=fopen("filesys","wb+")=NULL) /wb+:为读写建立一个"新"文件;打开系统文件将文件目录盘块和用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。+: 读和写 /位示图盘块写入系统文件printf("can not open file n");exit(0);fseek(fp,512L,0); / int fseek(FILE *stream, long offset, int fromwhere); 函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0,当前位置1,文件尾2)为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(offset超过文件自身大小),则不改变stream指向的位置。成功,返回0,否则返回其他值。fwrite(&emptytable,sizeof(struct empty),1,fp); /把结构体emptyable中的内容写入到fp中,数据项的大小为struct empty,数据项的个数为1fclose(fp);printf("!初始化系统成功!");void WriteFile() /将目录以及空闲盘块表写入磁盘 FILE *fp;if(fp=fopen("filesys","rb+")=NULL)printf("can not open file n");exit(0);rewind(fp); /将文件内部的位置指针重新指向一个流(数据流/文件)的开头for(int i=0;i<num;i+) fwrite(&filei,sizeof(struct filename),1,fp); /文件目录 fseek(fp,512L,0);fwrite(&emptytable,sizeof(struct empty),1,fp); /位示图fclose(fp);void dir() /显示文件目录 int i,j;FILE *fp;if(fp=fopen("filesys","rb")=NULL)printf("can not open file n");exit(0); fseek(fp,512L,0); /空闲盘块表的定位fread(&emptytable,sizeof(struct empty),1,fp);rewind(fp); /文件目录表的定位 num=emptytable.filenum;for(i=0;i<num;i+) fread(&filei,sizeof(struct filename),1,fp); if (num!=0) printf("系统所有文件:n"); for(i=0,j=1;i<num;i+,j+) printf("%s.%s",filei.name,filei.ext); if(j=5) printf("n"); j=1; printf("n文件数量为 %d ",num); fclose(fp);void type() /显示文件内容 FILE *fp;int i,j;if(fp=fopen("filesys","rb")=NULL)printf("can not open file n");exit(0); fseek(fp,512L,0); fread(&emptytable,sizeof(struct empty),1,fp); rewind(fp); num=emptytable.filenum; for(i=0,j=0;i<num;i+,j+) fread(&filei,sizeof(struct filename),1,fp); printf("%s.%s",filei.name,filei.ext); if(j=5) printf("n"); printf("n"); char name12,ext18; printf("请输入所要查询的文件名:n"); gets(name); /scanf("%s",name);/getchar(); printf("请输入扩展名:"); gets(ext1); /scanf("%s",ext1);getchar(); if(*(name+0)='0') printf("文件名不能为空 ! n"); return; if(*ext1='0') strcpy(ext1,"txt"); int sign=0; for(i=0;i<num;i+) if(strcmp(filei.name,name)=0) && (strcmp(filei.ext,ext1)=0) printf("-所找文件为第%d个文件-n",i+1); sign=1;break; if(sign=0) printf("无此文件n"); return; /显示文件 int b,m,n ; b=filei.i; n=filei.size; printf("-该文件位于第%d块n",b+1); printf("-从文件读出的文件长度为:%d-n",n); /fseek(fp,b*512L,0); char cc; printf("-文件内容为:-n");printf(""); for( m=0,j=1; m<n; m+,j+) fseek(fp,b*512L+m,0); /fread(&cc,sizeof(char),1,fp); cc=fgetc(fp); printf("%c",cc); if(j%40=0)printf("n"); printf("n"); fclose(fp);void delfile() /删除一个文件 FILE *fp;int i;if(fp=fopen("filesys","r")=NULL)printf("can not open file n");exit(0);fseek(fp,512L,0);fread(&emptytable,sizeof(struct empty),1,fp);rewind(fp);num=emptytable.filenum;for(i=0;i<num;i+)fread(&filei,sizeof(struct filename),1,fp);char name12,ext18;printf("请输入文件名:n");gets(name);/scanf("%s",name);getchar();printf("请输入扩展名:n");gets(ext1);/scanf("%s",ext1);getchar();if(*name='0')printf("文件名不能为空 ! n"); return; if(*ext1='0') strcpy(ext1,"txt");char judge;printf("是否删除文件%s.%s y/n",name,ext1);scanf("%c",&judge); getchar();if(judge='y')|(judge='Y')printf("准备删除文件%s.%s !n",name,ext1);else if(judge='n')|(judge='N') return;else printf("系统默认放弃!n"); return; int sign=0; for(i=0;i<num;i+)if(strcmp(filei.name,name)=0)&&(strcmp(filei.ext,ext1)=0)sign=1; break;if(sign=0) printf("文件名错n"); return; /回收空间int b=filei.i;int Amount=filei.Amount;int j;for(j=0;j<Amount;j+)emptytable.mapb+=0;for( j=i;j<num-1;j+) strcpy(filej.name,filej+1.name);strcpy(filej.ext,filej+1.ext);filej.i=filej+1.i;filej.size=filej+1.size;filej.Amount=filej+1.Amount; emptytable.filenum=emptytable.filenum-1; num=emptytable.filenum; WriteFile(); printf("删除成功!n"); fclose(fp);void copy() /复制一个文件 FILE *fq;int i,j,sign;if(fq=fopen("filesys","rb+")=NULL)printf("can not open file n"); exit(0);fseek(fq,512L,0);fread(&emptytable,sizeof(struct empty),1,fq);rewind(fq);num=emptytable.filenum;for(i=0;i<num;i+)fread(&filei,sizeof(struct filename),1,fq);/forchar SourceName12,DestName12,ext18,ext28;printf("请输入源文件名:");gets(SourceName); /scanf("%s",SourceName);getchar();printf("请输入源文件扩展名:");gets(ext1); /scanf("%s",ext1);getchar();printf("请输入目标文件名:");gets(DestName); /scanf("%s",DestName);getchar();printf("请输入目标扩展文件名");gets(ext2); getchar(); /scanf("%s",ext2);getchar();if(*ext2='0') strcpy(ext2,"txt");if(*SourceName)='0' | (*DestName)='0')printf("错误! 文件名不能为空!n");return;if(strcmp(SourceName,DestName)=0)printf("错误! 两个文件名不能相同!n");return;sign=0;for(i=0;i<num;i+) if(strcmp(SourceName,filei.name)=0) sign=1; strcpy(filenum.name,DestName); strcpy(filenum.ext,ext2); /filenum.i=filei.i; filenum.size=filei.size; filenum.Amount=filei.Amount; break; /for if(sign=0) printf("不存在源文件n");return;if (i<num)printf("输入的文件名与第%d个源文件相等(i从0开始)n",i); /空间分配sign=0;for(int m=2 ; m<=19-filenum.Amount ; m+) /* if(emptytable.mapm=0)for( j=filei.Amount; j>0; j-) /寻找一连续的空闲盘块if(emptytable.mapm+j-1=1)sign=1;break;/if/forif(sign=0) break;m+=j-1;sign=0; / forif (m <= 19-filenum.Amount)for(j=0;j < filenum.Amount;j+)emptytable.mapm+j=1;filenum.i=m;else printf("没有足够的连续的盘块数"); /写数据 FILE *fq1; rewind(fq); fq1=fq; fseek(fq,(filei.i) * 512L,0); printf("n-源文件的起始盘块号:%d",filei.i); /rewind(fp1); fseek(fq1,(filenum.i) * 512L,0); printf("n-复制文件的起始盘块号:%d",filenum.i); char cc; printf("n-源文件内容为:-n"); for(int k=0 ; k<filei.size;k+) fseek(fq,(filei.i) * 512L+k,0); fread(&cc,sizeof(char),1,fq); printf("%c",cc); fseek(fq1,(filenum.i) * 512L+k,0); fwrite(&cc,sizeof(char),1,fq1); printf("n"); num=num+1; emptytable.filenum=num; WriteFile(); /写目录及位示图 fclose(fq); fclose(fq1); void mkfile() /建立一个文件 FILE *fp;if(fp=fopen("filesys","r+")=NULL)printf("can not open filenpleace Initialization at firstn");exit(0);struct strNode /数据块char word64;struct strNode *next;*head,*p,*q;char name9,ext14;int i=0,j=0;head=p=q=new struct strNode; /申请结构体内存空间char ch;printf("请输入文件内容,按 键保存且退出!n"); dofor(i=0;i<64;i+)/ch=getchar(); scanf("%c",&ch);p->wordi=ch;if(ch='')break;if(ch!='')p=new struct strNode;q->next=p;q=p;j+;while(ch!=''); getchar(); int num1, size=(j*64+i)*sizeof(char); /j为结构体的个数,i为不足一个结构体的字符数 / printf("文件长度为:%dn",size); char judge='n' do printf("请输入文件的英文名字:"); gets(name);/scanf("%s",name);getchar(); printf("请输入文件的扩展名:"); gets(ext1);/scanf("%s",ext1);getchar();if(*ext1='0') strcpy(ext1,"txt");judge='y' if(*name='0')printf("错误!文件名不能为空!n");printf("是否放弃此文件Y/N ");scanf("%c",&judge);getchar();if( (judge='y') | (judge='Y') ) return; while( (judge='n') | (judge='N') ); fseek(fp,512L,0);fread(&emptytable,sizeof(struct empty),1,fp);rewind(fp);num=emptytable.filenum;/*for(i=0;i<num;i+)fread(&filei,sizeof(struct filename),1,fp);printf("%s.%sn",filei.name,filei.ext);*/for (i=0;i<num;i+)if(strcmp(filei.name,name)=0) && (strcmp(filei.ext,ext1)=0) printf("! 错误 ! 两个文件名不能相同n"); return;num1=size/512;if(size%512)>0) num1=num1+1;strcpy(filenum.name,name);/printf("%d%s%s",num,filenum.name,name);strcpy(filenum.ext,ext1);filenum.size = size;filenum.Amount=num1;int sign=0 ,n=0;/空间分配 for(int m=2 ; m <=10-num1; m+) /*if(emptytable.mapm=0) for(n=filenum.Amount; n>0; n-) if(emptytable.mapm+n-1=1)sign=1;break;/if /forif(sign=0)break;m+=n-1;sign=0;/if/forif(m<=10-num1)filenum.i = m; /*