【设计目的】
1. 课程设计目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能和内部实现。
2. 结合数据结构、程序设计、计算机原理等课程的知识,设计一个二级文件系统,进一步理解操作系统。
3. 通过对实际问题的分析、设计、编程实现,提高学生实际应用、编程的能力
【设计内容】
1、delete 删除文件
2、open 打开文件
3、close 关闭文件
4、write 写文件
【实验环境】
C++/VC++
【相关知识综述】
本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。
首先应确定文件系统的数据结构:主目录、子目录及活动文件等。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。
用户创建的文件,可以编号存储于磁盘上。如:file0,file1,file2…并以编号作为物理地址,在目录中进行登记。
【设计思路】
1 、主要数据结构
#define MAXNAME 25 /*the largest length of mfdname,ufdname,filename*/
#define MAXCHILD 50 /*the largest child每个用户名下最多有50个文件*/
#define MAX (MAXCHILD*MAXCHILD) /*the size of fpaddrno*/
typedef struct /*the structure of OSFILE定义主文件*/
{
int fpaddr; /*file physical address*/
int flength; /*file length*/
int fmode; /*file mode:0-Read Only;1-Write Only;2-Read and Write; 3-Protect;*/
char fname[MAXNAME]; /*file name*/
} OSFILE;
typedef struct /*the structure of OSUFD定义用户文件目录*/
{
char ufdname[MAXNAME]; /*ufd name*/
OSFILE ufdfile[MAXCHILD]; /*ufd own file*/
}OSUFD;
typedef struct /*the structure of OSUFD'LOGIN定义登陆*/
{
char ufdname[MAXNAME]; /*ufd name*/
char ufdpword[8]; /*ufd password*/
} OSUFD_LOGIN;
typedef struct /*file open mode定义操作方式*/
{
int ifopen; /*ifopen:0-close,1-open*/
int openmode; /*0-read only,1-write only,2-read and write,3-initial*/
}OSUFD_OPENMODE;
2 、主要函数及主要程序段说明
void LoginF(); /*LOGIN FileSystem*/
void DirF(); /*Dir FileSystem*/
void CreateF(); /*Create File*/
void DeleteF(); /*Delete File*/
void ModifyFM(); /*Modify FileMode*/
void OpenF(); /*Open File*/
void CloseF(); /*Close File*/
void ReadF(); /*Read File*/
void WriteF(); /*Write File*/
void QuitF(); /*Quit FileSystem*/
void CdF(); /*Change Dir*/
void help();
(1)Delete函数
void DeleteF() /*Delete File*/
{ char fname[MAXNAME],str[50],str1[50];
int i,k,j;
int fpaddrno1;
if (strcmp(strupr(ltrim(rtrim(dirname))),"")==0) /*无法删除主目录的文件*/
{
printf("\nError.Please convert to ufd dir before delete.\n");
wgetchar=1;
}
if (strcmp(strupr(dirname),strupr(username))!=0) /*无法删除非自己目录的文件*/
{
printf("\nError.You can only modify filemode in yourself dir.\n");
wgetchar=1;
}
else
{
printf("\nPlease input FileName:");
gets(fname);//从键盘获取所要删除的文件名
ltrim(rtrim(fname));
i=ExistF(fname);//获取文件编号
if (i>=0)
{
k=ExistD(username);
if(ifopen[k][i].ifopen==1)/*文件打开时无法删除*/
{
printf("\nError.\'%s\' is in open status. Close it before delete.\n",fname);
wgetchar=1;
}
else
{
if(ufd[k]->ufdfile[i].fmode==3)/*被保护的文件无法删除*/
{
printf("\nError.\'%s\' is in protect status. Close it before delete.\n",fname);
wgetchar=1;
}
else
{
fpaddrno1=ufd[k]->ufdfile[i].fpaddr;//获取文件对应的物理文件名
fpaddrno[fpaddrno1]=0;//回收盘块
for(j=i;j<fcount[k];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\'is deleted successfully.\n",fname);
wgetchar=1;
}
}
}
else//所要删除的文件不存在
{
printf("\nError. \'%s\' dose not exist.\n",fname);
wgetchar=1;
}
}
}
(2) Open函数
void OpenF() /*Open File*/
{
char fname[MAXNAME];
int i,k,j;
if (strcmp(strupr(dirname),strupr(username))!=0) /*在自己的目录里才能打开*/
{
printf("\nError.You can only open in yourself dir.\n");
wgetchar=1;
}
else
{
k=ExistD(username);
for(j=0;j<fcount[k];j++)
{
printf("%15s",ufd[k]->ufdfile[j].fname);
}
printf("\nPlease input FileName:");
gets(fname);//获取所要打开的文件名
ltrim(rtrim(fname));
i=ExistF(fname);//获取目录编号
if (i>=0)
{
if(ifopen[k][i].ifopen==1)//输入的文件是打开的
{
printf("\nError.\'%s\' is in open status.\n",fname);
wgetchar=1;
}
else
{
ifopen[k][i].ifopen=1;//修改为打开的
if(ufd[k]->ufdfile[i].fmode==0)/*根据文件的模式设置打开模式*/
{ ifopen[k][i].openmode=0;}
else if(ufd[k]->ufdfile[i].fmode==1)
{ifopen[k][i].openmode=1;}
else if(ufd[k]->ufdfile[i].fmode==2)
{ifopen[k][i].openmode=2;}
else ifopen[k][i].openmode=3;
printf("\n\'%s\' is opened successfully\n",fname);
wgetchar=1;
}
}
else//文件不存在
{
printf("\nError. \'%s\' dose not exist.\n",fname);
wgetchar=1;
}
}
}
(3) Close函数
void CloseF() /*Close File*/
{
char fname[MAXNAME];
int i,k,j;
if (strcmp(strupr(dirname),strupr(username))!=0) /*不在自己的目录里没法进行*/
{
printf("\nError.You can only close file in yourself dir.\n");
wgetchar=1;
}
else
{
k=ExistD(username);
for(j=0;j<fcount[k];j++)/*列出已经打开的文件*/
{
if(ifopen[k][j].ifopen==1)//如果文件是打开的
printf("%15s",ufd[k]->ufdfile[j].fname);
}
printf("\nPlease input FileName:");
gets(fname);//从键盘上读入所要关闭的文件
ltrim(rtrim(fname));
i=ExistF(fname);//获取文件编号
if (i>=0)
{
ifopen[k][i].ifopen=0;/*关闭文件*/
printf("\n \'%s\' closed successfully\n",fname);
wgetchar=1;
}
else//所要关闭的文件不存在
{
printf("\nError. \'%s\' dose not exist.\n",fname);
wgetchar=1;
}
}
}
(4) Write函数
void WriteF() /*Write File*/
{
int i,k,n=0;
int length;
char fname[MAXNAME],values[1000];
char str[255],str1[255],c;
if (strcmp(strupr(ltrim(rtrim(dirname))),"")==0) //只能写自己目录下的文件
{
printf("\nError.Please convert to ufd dir before write.\n");
wgetchar=1;
return;
}
printf("\nCaution:Open file first\n");
printf("Opened File(s) List:\n");
k=ExistD(dirname);//获取目录编号
for(i=0;i<fcount[k];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%d files openned.\n",n);
if (n==0) wgetchar=1;//没有打开的文件
if(n!=0)
{
printf("\nPlease input FileName:");
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%d Length.\n",ufd[k]->ufdfile[i].flength);
printf("\n\nYou have write file successfully!!");
fclose(fp_file);
wgetchar=0;
}
else if(ifopen[k][i].openmode==0)//文件是只读的
{
printf("\nError.\'%s\' has been opened with READ ONLY mode. It isn\'t write.\n",fname);
wgetchar=1;
}
else//文件是保护的
{
printf("\nError.\'%s\' has been opened with PROTECT mode. It isn\'t write.\n",fname);
wgetchar=1;
}
}
else //文件是关闭的
{
printf("\nError.\'%s\' is in closing status. Please open it before write\n",fname);
wgetchar=1;
}
}
else //所指定的文件不存在
{
printf("\nError. \'%s\' does not exist.\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、《实用操作系统教程》清华大学出版社20##年5月第一版 吴江红版
2、《嵌入式Linux操作系统原理与应用》北京航空航天大学出版社20##年3月第一版
文全刚 编著
二级文件目录结构:
二级文件目录结构为每个用户设置一张目录表,称为用户文件目录。用户文件目录为每一个文件设置一个目录项,再用一张总的目录表来登记各个用户的目录存放地址,这张总的目录表成为主文件目录。当用户需要访问某个文件时,系统根据每个用户名从主文件目录表中找到该用户的文件目录的存放地址,再按指定的文件名查找这张用户文件目录表,从用户文件目录表中找出对应目录项就可以找到文件存放的物理位置。
《操作系统原理》实验报告院(部):管理工程学院专业:信息管理与信息系统实验项目:实验一二三五班级:信管102姓名:学号:目录引言.…
西安郵電大學操作系统设计报告题目进程线程互斥锁院系名称计算机学院班级1104学生姓名赵大伟学号8位04113124指导教师舒新峰设…
操作系统课程论文院系班级姓名学号指导教师完成时间东莞理工学院摘要本文分析面向对象教学操作系统EOS的系统结构和代码构成通过源代码分…
操作系统课程设计实验报告姓名学号班级地点20xx年月日任务说明共完成四个任务任务一IO系统调用开销比较任务二实现一个简单的shel…
《操作系统原理》实验报告院(部):管理工程学院专业:信息管理与信息系统实验项目:实验一二三五班级:信管102姓名:学号:目录引言.…
上海电力学院计算机操作系统原理课程设计报告题目名称编写程序模拟虚拟存储器管理姓名杜志豪学号20xx1798班级20xx053班同组…