操作系统课程设计报告.docx
《操作系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告.docx(22页珍藏版)》请在冰豆网上搜索。
操作系统课程设计报告
操作系统课程设计报告
【设计目的】
1.课程设计目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能和内部实现。
2.结合数据结构、程序设计、计算机原理等课程的知识,设计一个二级文件系统,进一步理解操作系统。
3.通过对实际问题的分析、设计、编程实现,提高学生实际应用、编程的能力
【设计内容】
1、delete删除文件
2、open打开文件
3、close关闭文件
4、write写文件
【实验环境】
C++/VC++
【相关知识综述】
本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。
另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。
首先应确定文件系统的数据结构:
主目录、子目录及活动文件等。
主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。
用户创建的文件,可以编号存储于磁盘上。
如:
file0,file1,file2…并以编号作为物理地址,在目录中进行登记。
【设计思路】
1、主要数据结构
#defineMAXNAME25/*thelargestlengthofmfdname,ufdname,filename*/
#defineMAXCHILD50/*thelargestchild每个用户名下最多有50个文件*/
#defineMAX(MAXCHILD*MAXCHILD)/*thesizeoffpaddrno*/
typedefstruct/*thestructureofOSFILE定义主文件*/
{
intfpaddr;/*filephysicaladdress*/
intflength;/*filelength*/
intfmode;/*filemode:
0-ReadOnly;1-WriteOnly;2-ReadandWrite;3-Protect;*/
charfname[MAXNAME];/*filename*/
}OSFILE;
typedefstruct/*thestructureofOSUFD定义用户文件目录*/
{
charufdname[MAXNAME];/*ufdname*/
OSFILEufdfile[MAXCHILD];/*ufdownfile*/
}OSUFD;
typedefstruct/*thestructureofOSUFD'LOGIN定义登陆*/
{
charufdname[MAXNAME];/*ufdname*/
charufdpword[8];/*ufdpassword*/
}OSUFD_LOGIN;
typedefstruct/*fileopenmode定义操作方式*/
{
intifopen;/*ifopen:
0-close,1-open*/
intopenmode;/*0-readonly,1-writeonly,2-readandwrite,3-initial*/
}OSUFD_OPENMODE;
2、主要函数及主要程序段说明
voidLoginF();/*LOGINFileSystem*/
voidDirF();/*DirFileSystem*/
voidCreateF();/*CreateFile*/
voidDeleteF();/*DeleteFile*/
voidModifyFM();/*ModifyFileMode*/
voidOpenF();/*OpenFile*/
voidCloseF();/*CloseFile*/
voidReadF();/*ReadFile*/
voidWriteF();/*WriteFile*/
voidQuitF();/*QuitFileSystem*/
voidCdF();/*ChangeDir*/
voidhelp();
(1)Delete函数
voidDeleteF()/*DeleteFile*/
{charfname[MAXNAME],str[50],str1[50];
inti,k,j;
intfpaddrno1;
if(strcmp(strupr(ltrim(rtrim(dirname))),"")==0)/*无法删除主目录的文件*/
{
printf("\nError.Pleaseconverttoufddirbeforedelete.\n");
wgetchar=1;
}
if(strcmp(strupr(dirname),strupr(username))!
=0)/*无法删除非自己目录的文件*/
{
printf("\nError.Youcanonlymodifyfilemodeinyourselfdir.\n");
wgetchar=1;
}
else
{
printf("\nPleaseinputFileName:
");
gets(fname);//从键盘获取所要删除的文件名
ltrim(rtrim(fname));
i=ExistF(fname);//获取文件编号
if(i>=0)
{
k=ExistD(username);
if(ifopen[k][i].ifopen==1)/*文件打开时无法删除*/
{
printf("\nError.\'%s\'isinopenstatus.Closeitbeforedelete.\n",fname);
wgetchar=1;
}
else
{
if(ufd[k]->ufdfile[i].fmode==3)/*被保护的文件无法删除*/
{
printf("\nError.\'%s\'isinprotectstatus.Closeitbeforedelete.\n",fname);
wgetchar=1;
}
else
{
fpaddrno1=ufd[k]->ufdfile[i].fpaddr;//获取文件对应的物理文件名
fpaddrno[fpaddrno1]=0;//回收盘块
for(j=i;j{
ufd[k]->ufdfile[j]=ufd[k]->ufdfile[j+1];//从被删除的文件号开始,数组值全部前移一个
}
strcpy(str,"d:
\\osfile\\file\\file");
itoa(fpaddrno1,str1,10);//整数转化成字符串
strcat(str,str1);
strcat(str,".txt");
remove(str);//删除物理文件
fcount[k]--;//k用户文件数量少1
printf("\n\'%s\'isdeletedsuccessfully.\n",fname);
wgetchar=1;
}
}
}
else//所要删除的文件不存在
{
printf("\nError.\'%s\'dosenotexist.\n",fname);
wgetchar=1;
}
}
}
(2)Open函数
voidOpenF()/*OpenFile*/
{
charfname[MAXNAME];
inti,k,j;
if(strcmp(strupr(dirname),strupr(username))!
=0)/*在自己的目录里才能打开*/
{
printf("\nError.Youcanonlyopeninyourselfdir.\n");
wgetchar=1;
}
else
{
k=ExistD(username);
for(j=0;j{
printf("%15s",ufd[k]->ufdfile[j].fname);
}
printf("\nPleaseinputFileName:
");
gets(fname);//获取所要打开的文件名
ltrim(rtrim(fname));
i=ExistF(fname);//获取目录编号
if(i>=0)
{
if(ifopen[k][i].ifopen==1)//输入的文件是打开的
{
printf("\nError.\'%s\'isinopenstatus.\n",fname);
wgetchar=1;
}
else
{
ifopen[k][i].ifopen=1;//修改为打开的
if(ufd[k]->ufdfile[i].fmode==0)/*根据文件的模式设置打开模式*/
{ifopen[k][i].openmode=0;}
elseif(ufd[k]->ufdfile[i].fmode==1)
{ifopen[k][i].openmode=1;}
elseif(ufd[k]->ufdfile[i].fmode==2)
{ifopen[k][i].openmode=2;}
elseifopen[k][i].openmode=3;
printf("\n\'%s\'isopenedsuccessfully\n",fname);
wgetchar=1;
}
}
else//文件不存在
{
printf("\nError.\'%s\'dosenotexist.\n",fname);
wgetchar=1;
}
}
}
(3)Close函数
voidCloseF()/*CloseFile*/
{
charfname[MAXNAME];
inti,k,j;
if(strcmp(strupr(dirname),strupr(username))!
=0)/*不在自己的目录里没法进行*/
{
printf("\nError.Youcanonlyclosefileinyourselfdir.\n");
wgetchar=1;
}
else
{
k=ExistD(username);
for(j=0;j{
if(ifopen[k][j].ifopen==1)//如果文件是打开的
printf("%15s",ufd[k]->ufdfile[j].fname);
}
printf("\nPleaseinputFileName:
");
gets(fname);//从键盘上读入所要关闭的文件
ltrim(rtrim(fname));
i=ExistF(fname);//获取文件编号
if(i>=0)
{
ifopen[k][i].ifopen=0;/*关闭文件*/
printf("\n\'%s\'closedsuccessfully\n",fname);
wgetchar=1;
}
else//所要关闭的文件不存在
{
printf("\nError.\'%s\'dosenotexist.\n",fname);
wgetchar=1;
}
}
}
(4)Write函数
voidWriteF()/*WriteFile*/
{
inti,k,n=0;
intlength;
charfname[MAXNAME],values[1000];
charstr[255],str1[255],c;
if(strcmp(strupr(ltrim(rtrim(dirname))),"")==0)//只能写自己目录下的文件
{
printf("\nError.Pleaseconverttoufddirbeforewrite.\n");
wgetchar=1;
return;
}
printf("\nCaution:
Openfilefirst\n");
printf("OpenedFile(s)List:
\n");
k=ExistD(dirname);//获取目录编号
for(i=0;i{
if(ifopen[k][i].ifopen==1)//如果文件是打开的
{
printf("%15s",ufd[k]->ufdfile[i].fname);
n++;
}
if((n%4==0)&&(n!
=0))printf("\n");
}
printf("\n%dfilesopenned.\n",n);
if(n==0)wgetchar=1;//没有打开的文件
if(n!
=0)
{
printf("\nPleaseinputFileName:
");
gets(fname);//从键盘获取所要写的文件
ltrim(rtrim(fname));
i=ExistF(fname);//获取文件编号
if(i>=0)
{
if(ifopen[k][i].ifopen==1)//如果文件是打开的
{
if((ifopen[k][i].openmode==1)||(ifopen[k][i].openmode==2))//文件是只写,或者是可读可写的
{
itoa(ufd[k]->ufdfile[i].fpaddr,str,10);//获取文件对应的物理地址
strcpy(str1,"file");
strcat(str1,str);
strcpy(str,"d:
\\osfile\\file\\");
strcat(str,str1);
strcat(str,".txt");
fp_file=fopen(str,"ab");//以二进制只写的形式打开,每次将内容添加到文件末尾接着上一次内容
length=WriteF1();
ufd[k]->ufdfile[i].flength=ufd[k]->ufdfile[i].flength+length;//计算总长度
printf("\n\n%dLength.\n",ufd[k]->ufdfile[i].flength);
printf("\n\nYouhavewritefilesuccessfully!
!
");
fclose(fp_file);
wgetchar=0;
}
elseif(ifopen[k][i].openmode==0)//文件是只读的
{
printf("\nError.\'%s\'hasbeenopenedwithREADONLYmode.Itisn\'twrite.\n",fname);
wgetchar=1;
}
else//文件是保护的
{
printf("\nError.\'%s\'hasbeenopenedwithPROTECTmode.Itisn\'twrite.\n",fname);
wgetchar=1;
}
}
else//文件是关闭的
{
printf("\nError.\'%s\'isinclosingstatus.Pleaseopenitbeforewrite\n",fname);
wgetchar=1;
}
}
else//所指定的文件不存在
{
printf("\nError.\'%s\'doesnotexist.\n",fname);
wgetchar=1;
}
}
}
3、程序流程设计
(1)、总的功能结构图:
(2)打开命令(open)的程序流程图:
(3)关闭命令(close)的程序流程图:
(4)写命令(write)的程序流程图:
(5)删除命令(delete)的程序流程图:
【源程序清单】
见附页源代码
【测试结果】
1、打开文件(open)
2、读文件(read)
3、写文件(write)
(1)写文件成功
(2)写入失败,只读文件不能写
4、关闭文件(close)
5、删除文件(delete)
(1)处于打开状态的文件不能被删除
(2)先关闭文件(close),再删除文件
6、帮助指令(help)
7、切换已建目录文件(cd)
8、退出系统(Exit)
【设计总结】
UNIX系统中的文件系统是人们最感兴趣的,也是最成功的一部分。
它既有很强的功能,又非常灵活,而且在具体的实现技术上也有许多独到之处,致使后来有不少操作系统的设计者都仿效了UNIX操作系统中的文件系统去开发自己的文件系统。
而对于我来说,这种最灵活的知识却是最难掌握的。
也因为对其基本知识掌握的不好,在这一次的设计过程中遇到很多的困难,特别是物理盘块和逻辑文件之间的对应。
在经过与同学进行沟通和交流并反复的测试之后,才明白了设计的函数,而且完善了部分函数的主要功能。
通过两星期的操作系统课程设计实习,让我对Linux文件系统有了深层次的了解和掌握,也通过了自己的能力体会到了编程的乐趣。
最重要的是学会了关于设计分析和以前C++语言学习过程中没有及时巩固的知识,对C++程序设计又有了更进一步的认识,对一些细节的结构体语句有了更深刻的理解。
所以这是一次很难得的实践机会,让我真正用心编程,学到了课本以外更深刻更重要的实践经验。
非常感谢老师提供这次机会,在这个课程设计过程中我受益匪浅,希望以后在这样的锻炼中不断成长,提高自己各方面的能力
【参考文献】
1、《实用操作系统教程》清华大学出版社2011年5月第一版吴江红版
2、《嵌入式Linux操作系统原理与应用》北京航空航天大学出版社2011年3月第一版
文全刚编著
二级文件目录结构:
二级文件目录结构为每个用户设置一张目录表,称为用户文件目录。
用户文件目录为每一个文件设置一个目录项,再用一张总的目录表来登记各个用户的目录存放地址,这张总的目录表成为主文件目录。
当用户需要访问某个文件时,系统根据每个用户名从主文件目录表中找到该用户的文件目录的存放地址,再按指定的文件名查找这张用户文件目录表,从用户文件目录表中找出对应目录项就可以找到文件存放的物理位置。