操作系统 文件管理 课程设计.docx
《操作系统 文件管理 课程设计.docx》由会员分享,可在线阅读,更多相关《操作系统 文件管理 课程设计.docx(47页珍藏版)》请在冰豆网上搜索。
操作系统文件管理课程设计
一、课程设计题目和目的
通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识,加深对教材中的重要算法的理解。
同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。
二、课程设计要求
通过课程设计,要求学生主要掌握如下内容:
1.文件的物理结构可以选用顺序分配、链表分配或索引分配。
2.建立文件:
从命令中得到文件名,得到该文件的文件长度,建立文件。
修改目录表。
3.删除文件:
回收文件占用的空间,修改目录表
4.读文件:
read[文件名][显示开始字节][显示的字节数],直接显示所需要的字节数。
5.写文件:
write[文件名][插入的位置][插入的内容]
6.查询属性:
显示文件属性文件名,类型,长度,时间等。
三、程序设计思想
阅读操作系统方面的书籍,了解操作系统的文件系统原理。
结合分析课程设计要求,确定实体以及它们之间的关系。
实体关系有三张表(磁盘空间分配表、文件表、打开文件表)、一个模拟磁盘的数组、命令服务和用户构成。
用户负责输入命令。
命令服务实现命令的解释、命令检查、命令帮助以及调用相关模块执行相应的命令功能。
此课程设计把TXT文本作来研究对象来模拟操作系统的文件系统工作过程。
所以用一个字符串数组来模拟磁盘空间,顾名思义,模拟磁盘提供字符的存储服务。
磁盘空间分配表,采用链表结构,每个节点保存模拟磁盘的一个逻辑块的信息,包括块的最大长度,文件占用长度,占用标志。
如果占用标志为0,即该空间可分配给文件。
初始化磁盘空间分配表链表,首先把整个模拟磁盘作来一块,并置占用位为0.当有进程申请磁盘空间时,从头开始遍历,检查占用位,如果该块为可分配,则检查块大小,若块长度大于或等于申请空间大小,则把块的前一部分(等于申请大小)分配给文件,并置标志位为占用。
剩下的大小作来一个新块,作来一个新节点插入到原节点的后边,标志位为可用。
这样就实现了模拟磁盘的线性分配。
文件表,由于模拟文件系统的文件数量不多,故文件表采用线性表来存储。
线性表每个结点存储一个文件的信息。
打开文件表,采用数组形式存储打开的文件,数组每个元素保存一个打开文件的信息。
文件信息和文件表中的文件信息类似。
构造这些实体的关系图,数据流图、程序流程图来进行具体的设计。
四、文件系统的实现
1.数据结构设计
通过分析课程设计要求,具体设计出如下数据结构:
1chardisk[10000];//模拟磁盘空间
通过一个字符串数组来模拟磁盘空间,数组最大长度设置为10000,即磁盘空间最大容量为10000字节。
作为模拟文件系统,主要理解文件系统的原理,可以把文本文件作为对象来研究。
故磁盘空间用一个字符串数组来模拟.
2structfreeDiskTable//碰盘空间分配表
{
intstart;//开始位置
intlength;//占用长度
intmaxLength;//最大长度
intuseFlag;//使用标志,1为占用,0为空闲
};
通过结构体,将磁盘空间使用情况(文件开始位置、占用长度、最大长度、使用标志)结合在一体。
一个结构体变量记录磁盘一个块的信息。
结构体作为链表的一个节点,设置一个链表将节点连接起来,构成一个磁盘空间分配表。
3structfileTable//文件表
{
charfileName[20];//文件名字
intstart;//开始位置
intlength;//文件长度
intmaxLength;//最大长度
charfileKind[8];//文件种类,此默认为txt
structtm*timeinfo;//文件创建时间
};
通过结构体,将文件名字、文件在磁盘的开始位置、文件长度、文件最大长度、文件类型、创建时间结合在一起。
文件类型,本模拟程序使用txt类型。
设置一个线性表来存储文件。
4structopenFileTable//打开文件表
{
charfileName[20];//文件名字
charfileKind[8];//文件类型
intstart;//文件开始位置
intlength;//文件长度
intmaxLength;//最大长度
intopenCount;//打开文件的进程数
structtm*timeinfo;//文件创建时间
};
通过结构体存储打开的文件信息,包括文件名字、文件类型、文件开始位置、文件长度、最大长度、文件打开数和文件创建时间。
通过结构体数组存储所有打开文件信息。
2.程序功能图
文件系统提供的文件操作有建立文件(create)、删除文件(delete)、条件读取文件(read)、写入文件(write)、查询文件的属性(ask)、显示文件所有内容(type)、重命名文件(ren)、关闭文件(close)。
可以通过键盘输入命令来模拟文件的操作。
通过exit命令退出程序。
3.实体关系图
命令服务使得用户能够输入命令,在需要时提供命令的帮助。
同时能够分析命令,调用相应的命令模块对模拟磁盘、磁盘空间分配表、文件表、打开文件表进行操作。
磁盘空间分配表记录模拟磁盘的使用情况。
文件表记录文件的信息和在磁盘里的位置等信息。
打开文件表记录已打开的文件,对应文件表中的文件信息,和文件表里的文件节点类似,记录了文件在模拟磁盘中的信息。
4.数据流图
5.程序流程图
模拟文件系统提供的文件操作有建立(create),读取(read),显示(type),删除(detele),写入(write),关闭(close),重命名(ren)和查询(ask)。
在模拟程序中可从键盘上输入文件操作命令来模拟各用户程序中所调用的各种文件操作,用一个结束命令(exit)停止程序的执行。
(1).建立文件:
create(文件名,记录长度)
模拟文件系统进行“建立文件”的处理流程如下:
(2).写文件:
write(文件名,开始位置,字符串)
模拟文件系统进行“建立文件”的处理流程如下:
(3).读文件:
read(文件名,开始位置,长度)
模拟文件系统进行“读取文件”的处理流程如下:
(4).显示文件所有内容type(文件名)
和read方法类似,只不过是在参数上显示文件所有内容,故不再重复画流程图
(5).删除文件delete(文件名)
模拟文件系统进行“删除文件”的处理流程如下:
(6).重命名文件ren(文件名,新文件名)
模拟文件系统进行“重命名文件”的处理流程如下:
不在
在
不在
在
(7).查询文件属性ask(文件名)
模拟文件系统进行“查询文件属性”的处理流程如下:
(8).关闭文件close(文件名)
模拟文件系统进行“关闭文件”的处理流程如下:
五、程序运行结果及分析
1.程序主界面
2.输入create?
显示命令的帮助
3.创建一个长度为2000的文件createwhat2000
显示创建文件成功,并显示刚创建的文件信息
还有友情提示,create进程打开了文件what,需要用close命令关闭
4.往文件里写入内容writewhat0welcome!
显示成功写入,用type命令显示刚写入的内容,显示正确
5.继续从中间写入内容writewhat3test,之后用type命令显示内容,能得到正确结果
6.关闭文件closewhat
当计数器为0,显示成功关闭文件,结果比较满意
7.读文件readwhat34
读出来test字符串,结果正确
8.查询文件属性askwhat
显示了what文件的属性,结果正确,测试成功!
对于测试用例,还有很多路径都有测试过,鉴于篇幅,就不再列出所有可能的路径来进行白盒测试。
六、课程设计总结
通过本次的课程设计,使我能够正确运用操作系统课程中所学的基本理论和知识,加深了对文件系统基本概念的理解,以及磁盘文件系统的文件操作。
还有让我感受挺深的是对软件工程方法的应用。
设计一个软件,先要做好需求分析,这一点很重要,如果没有分析好需求,到软件设计的最后,发现所做的功能不符合要求,那么一切都得重做,前面所有的努力都付诸东流。
还有比较重要的是,写好E-R图,至少画出语境级的数据流图,以及仔细画好程流程图。
在程序设计的开始,由于分析工作做得不够深入和细致,吃了点小苦头。
对于这样一个小设计来说,都会吃苦头,要是大工程更是无法想像,有可能会项目失败。
以后得加强对软件工程的学习。
另外在运用C语言的时候,感觉有点生疏,在组织语言时时而出错,在编程和调试的过程中,经常会出现意想不到的问题,并非每个问题都可以从相关资料中找到解决方法,有些问题是无法预料到的,这就需要通过自己理性的分析得出问题的解决方案。
在设计过程中,查询了不少相关资料,不断的发现问题、提出问题、解决问题。
在对自己所编写的源程序段的纠错的过程中,使我更好的理解了操作系统中文件系统的理论知识,同时在编程时用到了模块化的设计思想,这种编程方法可以使我们的编程变的更简单,可以使我们的查错与纠错变的更方便。
总的来说通过这次的设计的学习使我学到了很多在平时的学习中学不到的很多东西,通过这次课程设计,使我对操作系统和编程产生兴趣,我想我会在这条路上继续前进下去。
我相信,只要不断的严格要求自己,注意培养自己的思维能力,就一定会有更大更辉煌的发展和提高。
七、参考文献
[1][美]AbrahamSilberschatzPeterBaerGalvinGregGagne郑扣根译.OPERATINGSYSTEMCONCEPTS[SixthEdition]操作系统概念.高等教育出版社,2004,01
[2](美)RogerS.Pressman著梅宏译.软件工程-实践者的研究方法.机械工业出版社,2002,09
[3]蔡启先.C语言程序设计教程(第二版).重庆大学出版社,2003,07
[4]朱战立.数据结构.西安电子科技大学出版社,2003,05
八、附录
1.程序源代码及注释
////////////////////////////////////////////////////////////
//编译工具:
Visualc++6.0//
////
//作者:
~小楚*smill~、蓝色的天空//
//邮件:
*******************//
////
//复制、传播请保留作者信息,谢谢!
//
////
////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
voidfileCreate(char*fileName,intfileLenght);//创建文件
voidfileDel(char*fileName);//删除文件
voidfileRead(char*fileName,intpostion,intlenght);
voidfileWrite(char*fileName,intposition,char*s);//函数声明
voidfileAsk(char*fileName);//查询文件属性
voidfileType(char*fileName);//显示文件内容
voidfileRen(char*fileName,char*newName);//重命名文件
voidfileDir();//列出所有文件
voidfileClose(char*fileName);//关闭一个文件
intrequestDisk(int*startPosition,int*maxLength);//分配磁盘空间
/////////////////////////////////
//模拟磁盘空间
chardisk[10000];
///////////////////////////////
//磁盘空间管理
structfreeDiskTable
{
intstart;//开始位置
intlength;//占用长度
intmaxLength;//最大长度
intuseFlag;//使用标志,1为占用,0为空闲
};
//////////////////////////////////
//文件表
structfileTable
{
charfileName[20];//文件名字
intstart;//开始位置
intlength;//文件长度
intmaxLength;//最大长度
charfileKind[8];//文件种类,此默认为txt
structtm*timeinfo;//文件创建时间
};
////////////////////////////////
//打开文件表
structopenFileTable
{
charfileName[20];//文件名字
charfileKind[8];//文件类型
intstart;//文件开始位置
intlength;//文件长度
intmaxLength;//最大长度
intopenCount;//打开文件的进程数
structtm*timeinfo;//文件创建时间
};
//////////////////////////////
typedefstructfreeDiskTableLinDataType;//定义链表的数据类型
#include"LinList.h"//链表操作集合
SLNode*freeDiskTableHead;//定义磁盘分配表链表头指针
#defineMaxSize100//定义线性表最大长度
typedefstructfileTableSeqDataType;//定义线性表数据类型
#include"SeqList.h"//线性表操作集合
SeqListL;//文件表,模拟文件操作嘛,文件数不多,故可以用线性表,简化操作^_^
structopenFileTableOFT[10];//打开文件表数组
intOFT_count=0;//打开文件表占用长度
voidmain()
{
structorderTable//命令表
{
charname[8];
};
charorderInput[30];//存储用户输入的命令字符串
charorderName[8];//命令名字
charfileName[20];//命令参数1,是文件名字
charparameter2[6];//命令参数2,是个数字
charparameter3[30];//命令参数3,是字符串或数字
structorderTableu[9];//命令表
inti=0;
intflag=0;//用户输入串读写位置标志
intflagOrder=-1;
/////////////////////////////////////
LinListInitiate(&freeDiskTableHead);//磁盘空间分配键表初始化
structfreeDiskTabletemp;
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;i<2;i++)
for(intj=0;j<2;j++)
{
system("colorfc");
printf("\n\n\n\n\n\n\n\n\n计046何珠举操作系统课程设计\n");
for(intk=0;k<30000000;k++);
system("cls");
system("colorf3");
printf("\n\n\n\n\n\n\n\n\n计046何珠举操作系统课程设计\n");
for(k=0;k<30000000;k++);
system("cls");
}
system("color17");//设置背景色和前景色
////////////////////////////////////////////////////////////
//初始化命令表
strcpy(u[0].name,"create");
strcpy(u[1].name,"delete");
strcpy(u[2].name,"read");
strcpy(u[3].name,"write");
strcpy(u[4].name,"ask");
strcpy(u[5].name,"type");
strcpy(u[6].name,"ren");
strcpy(u[7].name,"dir");
strcpy(u[8].name,"close");
////////////////////////////////////////////////////////////
while
(1)
{
printf("\n");
printf("|******************************************************|\n");
printf("|*create-创建delete-删除read-读取write-写入*|\n");
printf("|*ask-查询type-显示ren-重命名dir-显示文件*|\n");
printf("|*close-关闭文件*|\n");
printf("|*输入'命令?
'获得帮助,例如'create?
',exit-退出程序*|\n");
printf("|******************************************************|\n");
printf("请输入命令:
>");
fflush(stdin);//清空缓冲区
gets(orderInput);//获取用户输入串
if(!
strcmp(orderInput,"exit"))exit(0);//当用户输入exit退出程序
system("cls");//清屏
for(i=0;orderInput[i]!
=''&&orderInput[i]!
='\0';i++)//以空格为界分解用户输入串
{
orderName[i]=orderInput[i];
}
flag=i;//保存读写指针
if(flag>6)//命令名长度小于6
{
printf("输入的命令有误,请重新输入!
\n");
continue;
}
orderName[i]='\0';
flagOrder=-1;//初始化标志位,flagOrder指明命令在命令表中的位置
for(i=0;i<9;i++)
{
if(!
strcmp(orderName,u[i].name))
{
flagOrder=i;//记录命令的位置,以便访问
break;
}
}
if(flagOrder==-1)
{
printf("你输入的命令有误!
请重新输入!
\n");
continue;
}
/////////////////////////////////////////////////////
//以空格为界,分解字符串,分解出第一个字符串放到fileName中
for(i=flag+1;orderInput[i]!
=''&&orderInput[i]!
='\0';i++)
{
fileName[i-flag-1]=orderInput[i];
}
fileName[i-flag-1]='\0';//为字符串数组置一个结束标志
/////////////////////////////////////////////////////
flag=i;//下一个字符串读写指针
if(!
strcmp(fileName,"?
"))//显示命令帮助
{
switch(flagOrder)
{
case0:
printf("创建一个文件格式create[filename][filelength]\n");
printf("例如:
createa11000,将创建名为a1,长度为1000字节的文件\n");
break;
case1:
printf("删除一个文件格式delete[filename]\n");
printf("例如:
deletea1,将删除名为a1的文件\n");
break;
case2:
printf("读取一个文件格式read[filename][postion][length]\n");
printf("例如:
reada183,从a1文件第8个字节开始,显示3字节内容\n");
break;
case3:
printf("写一个文件格式write[fileName][postion][conten]\n");
printf("例始:
writea115test,从a1文件第15字节开始写入test字符串\n");
break;
case4:
printf("显示文件的属性,格式ask[filename]\n");
printf("例如aska1,将显示文件a1的属性\n");
break;
case5:
printf("显示文件的所有内容,格式type[filename]\n