资源描述
湖南工业大学
课 程 设 计
资 料 袋
学院(系、部) 学年第 学期
课程名称 计算机操作系统 指导教师 职称
学生姓名 专业班级 学号
题 目 文件系统演示
成 绩 起止日期 年 月 日~ 年 月 日
目 录 清 单
序号
材 料 名 称
资料数量
备 注
1
课程设计任务书
1
2
课程设计说明书
1
3
4
5
6
课程设计任务书
— 学年第 学期
学院(系、部) 专业 班级
课程名称: 计算机操作系统 学生姓名:
设计题目: 文件系统演示 指导教师:
完成期限:自 年 月 日至 年 月 日 共 周
内
容
及
任
务
一、设计内容
设计一个简单的多用户文件系统。即
①在系统中用一个文件来模拟一个磁盘;
②此系统至少有:Create、delete、open、close、read、write等和部分文件属性的功能。
③实现这个文件系统。
④能实际演示这个文件系统。
基本上是进入一个界面(此界面就是该文件系统的界面)后,可以实现设计的操作要求。
二、设计任务
课程设计说明书(纸质+电子版),内容包括:设计内容、系统分析(包括可行性分析、需求分析等)及功能分析;系统设计(要求画出系统整体功能框图、流程图、并给出相应地关键的代码且对所使用的主要数据结构进行说明等。)、设计总结(评价/遇到的问题/体会/建议等)、使用说明等。
三、设计要求
1. 按功能要求开发系统,能正确运行。程序代码书写规范,有充足的注释。
2. 课程设计所使用的编程语言任选,但建议使用C或C++;
3. 绿色软件:程序运行不需安装,避免写系统和注册表;
进
度
安
排
起止日期
工作内容
完成选题、课题分析、课题设计、编写程序
程序调试、完善代码
优化测试系统、程序答辩
撰写并提交课程设计说明书 (含电子文档)、源程序等。
主
要
参
考
资
料
[1] 胡志刚,谭长庚等. 《计算机操作系统》.中南大学出版社. 2005
[2] 罗宇,邹鹏,邓胜兰.操作系统[M].北京:电子工业出版社,2012.
[3] 面向对象程序设计与C++语言.朱战立,宋新爱.电子工业出版社,2010.7
[4] C++面向对象程序设计.谭浩强.清华大学出版社,2006.1
[5] 任爱华,李鹏,刘方毅.操作系统实验指导, 清华大学出版社,2004.
[6] 徐虹.操作系统实验指导-基于LINUX内核, 清华大学出版社, 2004.
指导教师(签字): 年 月 日
系(教研室)主任(签字): 年 月 日
计算机操作系统课程设计
设计说明书
文件系统演示
起止日期: 年 月 日 至 年 月 日
学生姓名
班级
学号
成绩
指导教师(签字)
计算机与通信学院
年 月 日
目 录
1 课程设计简介 1
1.1 课程设计的目的 1
1.2 课程设计内容 1
2 数据结构的设计 1
2.1全局变量设计 1
2.2结构体设计 1
2.3函数设计 3
3 功能模块(或算法)描述 3
4 程序运行结果 6
5心得体会 8
参考文献 9
附源代码 10
1 课程设计简介
1.1 课程设计的目的
课程设计目的使学生熟悉文件管理系统的设计方法;加深对所学各种文件操作的了解及其操作方法的特点。通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。
1.2 课程设计内容
设计一个简单的多用户文件系统。即:
①在系统中用一个文件来模拟一个磁盘;
②此系统至少有:Create、delete、open、close、read、write等和部分文件属性的功能。
③实现这个文件系统。
④能实际演示这个文件系统。基本上是进入一个界面(此界面就是该文件系统的界面)后,可以实现设计的操作要求。
2 数据结构的设计
2.1全局变量设计
#define MaxDisk 512*1024 //一个扇区512字节,假设有1024个扇区
int Max_User=10; //支持的最大用户数
int Max_Open=5; //文件的最大打开数
int Max_End=0; //存放最大的末点
UFD_ptr pufd=NULL; //UFD的头结点
MFD_ptr pmfd=NULL; //MFD的头结点
AFD_ptr pafd=NULL; //AFD的头结点
char User_name[30]; //存放当前用户的用户名
char flag='n';
char Disk_Size[MaxDisk]; //模拟磁盘
Disk_Node Disk_Head; //磁盘空间控制结点
2.2结构体设计
typedef struct UFD
{
string File_name; //文件名
int Start; //文件在磁盘存储空间的起始地址
int Protect; //文件的属性
int File_length; //文件的长度
int Max_File_length; //文件的最大长度
struct UFD *next;
}UFD,*UFD_ptr;
typedef struct MFD
{
string User_name; //用户名
string User_passwd; //用户密码
UFD *Ufd_next; //UFD指针
int End; //用户空间分配的末尾
struct MFD *next; //MFD指针
}MFD,*MFD_ptr;
typedef struct AFD
{
string File_name;
int File_length;
int Start; //文件在磁盘存储空间的起始位置
int Protect; //文件权限
int Pointer; //根据这个指针的值去完成用户的要求,读写指针
int Max_File_length; //文件的最大长度
struct AFD *next; //AFD指针
}AFD,*AFD_ptr;
typedef struct Disk_Table
{
int Max_length; //最大长度
int Start; //开始位置
}Disk_Node;
2.3函数设计
void Init_Disk();磁盘初始化函数
bool Init_MFD();MFD链表初始化函数
void Print_UFD();UFD文件打印输出函数
bool Init_UFD(char *name);UFD链表初始化函数
bool User_Check();用户检索函数
void Init_AFD();AFD链表初始化函数
bool Create_MFD();MFD文件创建函数
bool Create_UFD();UFD文件创建函数
bool Delete_UFD();UFD文件删除函数
bool Open();UFD文件打开函数
void Close();UFD文件关闭函数
bool Read_File();UFD文件读取函数
bool Write_File();UFD文件写入函数
void Destroy_Space();系统释放资源函数
void Save_MFD();MFD文件保存函数
void Save_UFD(char *name);UFD文件保存函数
void Quit_System();系统退出函数
void Print_Help();用户帮助菜单函数
void System_Init();系统初始化函数
void File_System();系统操作函数
3 功能模块(或算法)描述
3.1文件系统结构如下:
HQ
∧
MFD
UFD
HQ1
CW1
图3.1文件系统总体数据结构图
3.2文件系统算法的流程图如图3.2所示。
图3.2文件系统算法流程图
3.3 login 登录
用户输入用户名和密码,在MFD文件中查找是否有此用户,核对密码。正确则登录成功,当前目录设定到当前用户文件夹下。如果用户密码输错3次,系统结束。
3.4 create 创建文件
查找当前用户目录下是否有同名文件,是则退出,否则让用户输入新建文件的相关属性;并为之模拟分配磁盘空间。
3.5 delete 删除文件
查找文件是否已经打开,打开则退出,因为打开代表该资源正被占用,无法释放或者删除;没有打开则检查该文件是否存在,显然,你是不可以删除一个不存在的文件的,存在便将该文件删除,并回收相应的资源。
3.6 ls 查看文件的属性
将用户目录下的所有文件相关信息显示出来;其中包括文件名、、最大文件长度、文件权限、起始位置、文件长度信息。
3.7 open 打开用户文件
首先判断用户欲打开的文件是否已经打开,已经打开自然不需要打开了。再是判断用户欲打开的文件是否属于该用户的文件;排除以上两点后,将用户指定的文件打开来。
3.8 close 关闭用户文件
首先判断用户欲打开的文件是否已经打开,如果文件是关闭的,自然就不需要再进行关闭操作了,直接返回退出函数的调用即可;再就是判断用户欲关闭的文件是否属于该用户的文件,排除以上两点后,将用户指定的文件关闭掉。
3.9 read 读取文件内容
首先判断欲读取的文件是否已经打开,按照常理来讲,要想先读文件,自然得先打开文件,好比office里的word一样。紧接着根据用户的要求完成文件内容的读取操作,显然读取操作得要求文件至少有读取的权限,关于这点,我们程序是通过open命令功能来判断的。
3.10 write写入文件内容
同样,用户要求写入文件的话,首先该文件要先打开,并且具有可写入信息的权限;而且文件的属主自然是该用户,用户可以根据自己的需要写入指定长度内容的数据,在我们的程序中,一个字符代表一个字节。
3.11 logout 登出用户
可以达到间接切换用户的功效,既然是登出用户,上一次登录用户的操作变化自然是需要保存的,并且所占用的资源也需要释放掉。用户登出后实则再次转入到用户的登录界面。
图3.3 登录模块流程图 图3.4 读取模块流程图 图3.5 写入模块流程图
注释:在读取和写入数据时,其实还要有文件是否打开判断的,这里没画出来而已。
4 程序运行结果
4.1 显示帮助信息并登录
4.2 显示UFD的相关信息
4.3 创建用户文件
文件保护类型说明:0代表不可操作,1代表可读,2代表可读可写
4.4 删除用户文件
对比4.3,显然可以知道,程序的确将HQ3文件给删除了。
4.5 打开文件操作
根据上下两图的对比,HQ1的确是打开了,以致于再次打开失败。
4.6 关闭文件操作
由上图可知,HQ1文件的确是被关闭了,以致于再次关闭失败。
4.7 写入文件内容
和我们之前说的一样,要对一个文件进行写入操作,你自然要先打开这个文件,用户可以根据自己写入数据大小的需要对该文件写入指定大小的内容。但这也是不能超过文件的分配容量的,否则数据溢出了。
为了文件系统模拟实现起来比较方便,将用户文件的相关信息输出到一个文件中去,这样可以避免再次输入带来的麻烦。可以发现,我们刚刚对HQ5文件写入了20字节大小的数据,确实是写入进去了。说明一下:#表示文件是空的,用户并没有对该文件写入任何数据,只是占了空间而已。
4.8 读取文件内容
上图直观的显示出read读取HQ5文件的内容,也就是我们刚刚写入的文件信息,这也是符合我们的逻辑观念,有的时候用户仅仅想读取文件的一部分内容。
5心得体会
操作系统课程设计,自己通过查找资料、复习课本、编程调试,写实验报告等环节,进一步掌握了以前学到的知识,并且还对操作系统应用有了更深入的认识与掌握。比如对树的展示有了很好的学习,对二级文件系统也有了很好的了解,如何解决实现里面功能的各种问题。 通过实践的学习,我认到学好计算机要重视实践操作,不仅要学习C/C++语言,还要学习一些其他语言,以及其它的计算机方面的知识都要重在实践,所以后在学习过程中,我会更加注视实践操作,使自己便好地学好计算机。
操作系统课程设计是本课程重要的实践教学环节。课程设计的目的,一方面使学生更透彻地理解操作系统的基本概念和原理,使之由抽象到具体;另一方面,通过课程设计加强学生的实验手段与实践技能,培养学生独立分析问题、解决问题、应用知识的能力和创新精神。与本课程的实验教学相比,课程设计独立设课,具有更多的学时,给学生更多自行设计、自主实验的机会,充分放手让学生真正培养学生的实践动手能力,全面提高学生的综合素质。
在设计的过程中遇到问题,可以说得是困难重重,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,不过设计终于顺利完成了,在设计中遇到了很多编程问题,最后在老师的辛勤指导下,终于游逆而解。同时,在老师的身上我学得到很多实用的知识,再次我表示感谢!
参考文献
[1] 胡志刚,谭长庚等. 《计算机操作系统》.中南大学出版社. 2005
[2] 罗宇,邹鹏,邓胜兰.操作系统[M].北京:电子工业出版社,2012.
[3] 面向对象程序设计与C++语言.朱战立,宋新爱.电子工业出版社,2010.7
[4] C++面向对象程序设计.谭浩强.清华大学出版社,2006.1
[5] 任爱华,李鹏,刘方毅.操作系统实验指导, 清华大学出版社,2004.
[6] 徐虹.操作系统实验指导-基于LINUX内核, 清华大学出版社, 2004.
附源代码
头文件部分:
#include<cmath>
#include<ctime>
#include<string>
#include<conio.h>
#include<fstream>
#include<cstdlib>
#include<iostream>
#include<windows.h>
using namespace std;
typedef struct UFD{
string File_name; //文件名
int Start; //文件在磁盘存储空间的起始地址
int Protect; //文件的属性
int File_length; //文件的长度
int Max_File_length; //文件的最大长度
struct UFD *next;
}UFD,*UFD_ptr;
typedef struct MFD{
string User_name;
string User_passwd;
UFD *Ufd_next;
int End;
struct MFD *next;
}MFD,*MFD_ptr;
typedef struct AFD{
string File_name;
int File_length;
int Start;
int Protect;
int Pointer; //根据这个指针的值去完成用户的要求 读写指针
int Max_File_length;
struct AFD *next;
}AFD,*AFD_ptr;
typedef struct Disk_Table
{
int Max_length; //最大长度
int Start; //开始位置
}Disk_Node;
源文件部分:
#include"os_fss.h"
#define MaxDisk 512*1024 //一个扇区512字节,假设有1024个扇区,模拟磁盘的大小
int Max_User=10;
int Max_Open=5;
int Max_End=0;
UFD_ptr pufd=NULL;
MFD_ptr pmfd=NULL;
AFD_ptr pafd=NULL;
char User_name[30]; //存放当前用户的用户名
char flag='n';
char Disk_Size[MaxDisk]; //最后在打印输出的时候,用RWX表示即可
Disk_Node Disk_Head;
void Init_Disk()
{
Disk_Head.Max_length=MaxDisk;
Disk_Head.Start=0;
}
bool Init_MFD()
{
pmfd=(MFD *)new MFD; //带头节点的单向链表
MFD *p=pmfd;
ifstream ifs("MFD.txt"); //文件的输入流对象
if(!ifs){
cerr<<"错误:无法打开文件"<<endl;
p->next=NULL;
p->Ufd_next=NULL;
return false;
}
while(!ifs.eof()){
p->next=(MFD *)new MFD;
ifs>>p->next->User_name>>p->next->User_passwd>>p->next->End;
if(p->next->End>Max_End)
Max_End=p->next->End;
p=p->next;
p->Ufd_next=NULL;
p->next=NULL;
}
ifs.close();
return true;
}
void Print_UFD()
{
UFD *p=pufd->next;
if(!p){
cout<<"抱歉,该用户没有创建任何文件,请先创建!!!"<<endl;
return ;
}
cout<<"文件名\t\t最大文件长度\t文件权限\t起始位置\t文件长度"<<endl;
while(p){
cout<<p->File_name<<"\t\t"<<p->Max_File_length;
if(p->Protect==0)
cout<<"\t\t"<<"---";
else if(p->Protect==1)
cout<<"\t\t"<<"r-x";
else if(p->Protect==2)
cout<<"\t\t"<<"rwx";
cout<<"\t\t"<<p->Start;
cout<<"\t\t"<<p->File_length<<endl;
p=p->next;
}
}
bool Init_UFD(char *name)
{
ifstream ifs(name);
pufd=(UFD *)new UFD;
UFD *p=pufd;
char temp[MaxDisk];
bool Index=false;
if(!ifs){
cerr<<"错误:无法打开文件"<<endl;
p->next=NULL;
return false;
}
while(!ifs.eof()){
memset(temp,'\0',sizeof(temp));
p->next=(UFD *)new UFD;
if(!Index){
pmfd->Ufd_next=p->next;
Index=true;
}
ifs>>p->next->File_name>>p->next->Max_File_length>>p->next->Protect
>>p->next->Start>>p->next->File_length;
ifs>>temp;
if(temp[0]=='#')
temp[0]='\0';
for(int i=p->next->Start,j=1;j<=p->next->Max_File_length-1;i++,j++)
{
Disk_Size[i]=temp[j-1];
if(!Disk_Size[i])
break;
}
Disk_Head.Max_length-=p->next->Max_File_length;
p=p->next;
p->next=NULL;
}
ifs.close();
return true;
}
bool User_Check()
{
string User_passwd;
int Count=0;
while(1){
cout<<"请输入用户名:";
cin>>User_name;
INIT:
cout<<"请输入密码:";
cin>>User_passwd;
MFD *p=pmfd->next;
char temp[30];
memset(temp,'\0',sizeof(temp));
strcpy(temp,User_name);
Count++;
while(p){
if(User_name==p->User_name){
if(User_passwd==p->User_passwd)
cout<<"登入成功."<<endl;
else{
cout<<"抱歉,密码错误,登陆失败,请重新输入!!!"<<endl;
if(Count==3){
cout<<"密码错误次数过多,系统运行结束!!!"<<endl;
return false;
}
goto INIT;
}
strcat(temp,".txt");
Init_UFD(temp);
Disk_Head.Start=Max_End;
return true;
}
p=p->next;
}
cout<<"用户名不存在,请重新输入!!!"<<endl;
}
}
void Init_AFD()
{
pafd=(AFD *)new AFD;
pafd->next=NULL;
}
bool Create_MFD()//创建文件命令
{
string User_name;
char User_passwd[30];
MFD *p = pmfd;
cout<<"请输入要创建的用户名: ";
cin>>User_name;
cout<<"请输入"<<User_name<<"用户的密码:(默认为:admin)";
getchar();
cin.getline(User_passwd,30);
if(User_passwd[0]=='\0')
strcpy(User_passwd,"admin");
while(p){
if(User_name==p->User_name){
cout<<"此用户名已存在!!!"<<endl;
return false;
}
if(!p->next)
break;
p= p->next;
}
p->next = (MFD *)new MFD; //尾插法
p=p->next;
p->User_name=User_name;
p->User_passwd=User_passwd;
p->End=0;
p->next = NULL;
p->Ufd_next = NULL;
Max_User--;
return true;
}
bool Create_UFD()//创建文件命令
{
string File_name;
UFD *p = pufd;
unsigned int Protect;
int Max_File_length;
cout<<"请输入要创建的文件名: ";
cin>>File_name;
cout<<"请输入要创建的文件保护类型:";
cin>>Protect;
cout<<"请输入文件的最大容量:"<<endl;
cin>>Max_File_length;
while(p){
if(File_name==p->File_name){
cout<<"此文件名已存在!!!"<<endl;
return false;
}
if(!p->next)
break;
p= p->next;
}
p->next = (UFD *)new UFD; //尾插法
p=p->next;
p->File_name=File_name;
p->Max_File_length=Max_File_length;
p->Start=Disk_Head.Start;
p->Protect = Protect;
p->File_length = 0; //刚创建文件时,文件是空的
Disk_Head.Start+=Max_File_length;
p->next = NULL; //我觉得这部分代码有问题;用户创建了一个文件
return true; //并不代表该文件就被打开了
} //关于主目录的用户文件夹的文件删除-->先这样写,好吧
bool Delete_UFD() //如果文件已经打开了,是不能删除的
{
string File_name;
cout<<"请输入要删除的文件名:";
cin>>File_name;
UFD *p=pufd,*temp;
AFD *pa=pafd;
while(pa->next){
if(File_name==pa->next->File_name){
cout<<"抱歉,该文件已被打开,请先关闭,再进行删除操作!!!"<<endl;
return false;
}
}
while(p->next){
if(File_name==p->next->File_name){
temp=p->next;
p->next=p->next->next; //如果说要回收模拟的磁盘
delete temp; //空间的话,应该是回收最大长度
cout<<"文件删除成功!!!"<<endl;
return true;
}
p=p->next;}
cout<<"抱歉,要删除的文件不存在!!!"<<endl;
return false;
}
bool Open()
{
string File_name;
unsigned int Protect;
cout<<"请输入要打开的文件名:";
cin>>File_name;
UFD *p=pufd->next;
AFD *pa=pafd->next;
while(pa){
if(File_name==pa->File_name){
cout<<"文件"<<File_name<<"已经打开!!!"<<endl;
return true;
}
if(!pa->next)
break;
pa=pa->next;
}
if(!pa) //如果找不到,或者打开的文件目录链表为空表
pa=pafd;
while(p){
if(File_name==p->File_name){
if(!Max_Open){
cout<<"抱歉,最多只能打开5个文件,请先关闭其他打开的
文件再操作!!!"<<endl;
return false;
}
if(p->Protect==0){
cout<<"抱歉,此文件不可执行任何操作!!!"<<endl;
return false;
}
cout<<"请选择以什么样的方式打开文件<1-只读,2-可读可写>:";
cin>>Protect;
pa->next=(AFD *)new AFD;
pa=pa->next;
pa->File_name=p->File_name;
pa->Start=p->Start;
pa->File_length=p->File_length;
pa->Max_File_length=p->Max_File_length;
pa->Protect=Protect;
if(Protect==1)
pa->Pointer=0; //Poniter取0表示此时用户无法写数据(没有空间的含义)
else
pa->Pointer=p->File_length;
pa->next=NULL;
Max_Open--;
cout<<"文件"<<File_name<<"已经打开!!!"<<endl;
return true;
}
p=p->next;
}
cout<<"抱歉,要打开的文件不存在!!!"<<endl;
return false;
}
void Close()
{
string file_name;
UFD *pu=pufd->next;
cout<<"请输入要关闭的文件名:";
cin>>file_name;
AFD *p=pafd,*temp;
while(p&&p->next){
if(file_name==p->next->File_name){
temp=p->next;
p->next=p->next->next;
if(temp->Protect==2) //可写的文件才有权把新写入的数据也保存起来嘛
{
while(pu){
if(temp->File_name==pu->File_name){
pu->File_length=temp->Pointer;
break;
}
pu=pu->next;
}
}
delete temp;
cout<<"文件"<<file_name<<"关闭成功!!!"<<endl;
return ;
}
p=p->next;
}
cout<<"抱歉,要关闭的文件没有被打开!!!"<<endl;
}
bool Read_File() //因为读写都是通过修改运行文件目录的Pointer去模拟的嘛
{
string File_name; //你要读文件的话,你这文件肯定得在运行/打开文件目录里面,是吧
unsigned int length;
AFD *p=pafd->next;
cout<<"请输入要读的文件名:";
cin>>File_name;
cout<<"请输入都读取的长度:"; //读取的话,实际中文件的长度并不会改变
cin>>length; //即读取的长度并不能保存回去
while(p) //为了方便(如果用户是读数据的话,pointer始终不变)
{
if(File_name==p->File_name){
for(int i=p->Start,j=1;j<=length;i++,j++)
cout<<Disk_Size[i];
cout<<endl;
cout<<"文件"<<File_name<<"读取成功!!!"<<endl;
return true;
}
p=p->next;
}
cout<<"读取失败,文件没有打开过!!!"<<endl;
return false;
}
bool Write_File() //写的话,自然是运行文件目录
{
string File_name;
unsigned int length;
AFD *p=pafd->next;
char temp[MaxDisk]={'\0'};
cout<<"请输入要写的文件名:";
cin>>File_name;
while(p){
if(File_name==p->File_name){
if(p->Protect!=2){
cout<<"文件"<<File_name<<"不可写"<<endl;
r
展开阅读全文