这个学期学习操作系统,其实主要就是系统对于一些情况的应对算法,我们要做的就是写代码模拟这个情况,来了解操作系统是怎么解决的。
一、简介
文件系统是操作系统的一个重要组成部分,也是与用户关系极为密切的部分。编写和调试一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
对文件的操作至少应有下面几条命令:
create 建立文件
delete 删除文件
open 打开文件
close 关闭文件
read 读文件(执行)
write 写文件
二、算法
设计一个共有10个用户的文件系统,每个用户最多可保存10个文件,一次运行过程中用户可同时打开5个文件。系统应能检查输入命令的正确性,出错时要能显示出错原因。对文件必须设置保护措施,如只能执行,允许读,允许写等。在每次打开文件时,根据本次打开的要求,再次设置保护级别,即可有二级保护。
文件保护简单使用了三位保护码,对应于允许读,允许写和允许执行,如下所示:
如对应位为0,则不允许。
1 | 1 | 1 |
---|---|---|
允许读 | 允许写 | 允许执行 |
程序采用二级文件目录,即设置了主文件目录(MFD)和用户文件目录(UFD)。前者应包含文件主(即用户)及他们的目录区指针;后者应给出每个文件主占有的文件目录,即文件名、保护码、文件长度以及它们存放的位置等。另外为打开文件设置了运行文件目录(AFD),在文件打开时应填入打开文件号,本次打开保护码和读写指针等。
三、结果
四、代码
#include<iostream>
#include<malloc.h>
#include<string.h>
using namespace std;
typedef struct ufd//用户文件目录
{
char filename[20];
bool fileprotect[3];//在c++中,bool类型按非零为true,是零为false规则执行
bool openprotect[3];//仅在文件打开时有效
int read,write;//定义为读写指针
int filelength;
struct ufd *next;
}UFD;
typedef struct mfd//主文件目录
{
char userName[20];
int maxfile;//每个用户最多拥有文件数
UFD *ufd;
struct mfd *next;
}MFD;
typedef struct afd//打开文件目录
{
UFD *head,*tail;
int maxopen;
int currentopen;//当前打开文件数
} AFD;
MFD *head,*tail;//主文件目录指针
void initUser();//进行用户的初始化
void displayUser();//进行系统用户的输出
MFD* queryUser(char userName[]);//进行用户的查找,找到则返回用户映射指针
bool createFile(MFD *user, char filename[],bool fileprotect[3],int filelength);//进行文件的创建操作,成功则返回true,否则返回false
bool deleteFile(MFD *user,char filename[],AFD *afd);//进行文件删除操作
bool openFile(MFD *user,char filename[],AFD *afd,bool openprotect[]);//进行文件打开操作
bool readFile(AFD *afd,char filename[]);//进行读操作
bool writeFile(AFD *afd,char filename[]);//进行文件的写操作
bool closeFile(AFD *afd,char filename[]);//关闭文件
void displayUserFile(MFD *user);//进行用户文件的显示
void displayOpenFile(AFD *afd,MFD *user);//显示打开的文件
void setfile(char userName[],MFD *user)//对文件进行各种操作
{
AFD *afd;//为用户初始化打开文件目录
afd = (AFD*)malloc(sizeof(AFD));
if(afd == NULL)
{
cout<<"内存不足,请重试!"<<endl;
exit(0);
}
afd->head = afd->tail = NULL;
afd->maxopen = 5;//最多同时打开5个文件
afd->currentopen = 0;
int command;
char filename[20];
bool fileprotect[3];
bool openprotect[3];
int filelength;
while(true)
{
cout<<"*******************欢迎进入个人文件系统!*******************"<<endl;
cout<<"** 1、创建文件\t3、打开文件\t5、执行文件 **"<<endl;
cout<<"** 2、删除文件\t4、关闭文件\t6、写入文件 **"<<endl;
cout<<"** 0、退出登陆 **"<<endl;
cout<<"************************************************************"<<endl;
cout<<userName<<"$ ";
cin>>command;//输入命令进行操作
switch(command)
{
case 1:
cout<<"请输入文件名,保护码(示例:1 0 1),文件长度:";
cin>>filename>>fileprotect[0]>>fileprotect[1]>>fileprotect[2]>>filelength;
createFile(user,filename,fileprotect,filelength);
displayUserFile(user);
break;
case 2:
cout<<"请输入要删除的文件名:";
cin>>filename;
deleteFile(user,filename,afd);
displayUserFile(user);
break;
case 3:
cout<<"请输入要打开的文件名,保护码(示例:1 0 1):";
cin>>filename>>openprotect[0]>>openprotect[1]>>openprotect[2];
openFile(user,filename,afd,openprotect);
displayOpenFile(afd,user);
break;
case 4:
cout<<"请输入要关闭的文件名:";
cin>>filename;
closeFile(afd,filename);
displayOpenFile(afd,user);
break;
case 5:
cout<<"请输入要执行的文件名:";
cin>>filename;
readFile(afd,filename);
displayOpenFile(afd,user);
break;
case 6:
cout<<"请输入要写入的文件名:";
cin>>filename;
writeFile(afd,filename);
displayOpenFile(afd,user);
break;
case 0:
cout<<"您已退出登陆!"<<endl;
return;
break;
default:
cout<<"没有这项操作!"<<endl;
break;
}
}
}
int main()
{
initUser();
char userName[20];
while(true)
{
displayUser();
cout<<"(退出程序输入0)请选择一位用户登陆:";
cin>>userName;
if(userName==0)break;
MFD *user;
user = queryUser(userName);
if(user == NULL)cout<<"没有此用户,请重新输入!"<<endl;
else
{
setfile(userName,user);//这个函数要想退出,必然是用户输入0要求退出
//head=tail=NULL;
}
}
return 0;
}
void initUser()
{
cout<<"请输入十位用户的名字:"<<endl;
for(int i = 1; i <= 10; i++)//初始化十个不同用户
{
MFD *m;
m = (MFD*)malloc(sizeof(MFD));
if(m == NULL)
{
exit(0);
}
cin>>m->userName;
m->ufd = NULL;
m->next = NULL;
m->maxfile = 0;//每位用户最多拥有10个文件.当前拥有0个文件
if(head == NULL)
{
head = tail = m;
}
else
{
tail->next = m;
tail = m;
}
}
}
void displayUser()
{
MFD *m = NULL;
m = head;
cout<<"用户列表:";
while(m)
{
cout<<m->userName<<" ";
m = m->next;
}
cout<<endl;
}
MFD* queryUser(char userName[])
{
MFD *m = NULL;
m = head;
while(m)
{
if(strcmp(userName,m->userName) == 0)
{
return m;
}
m = m->next;
}
return NULL;
}
bool createFile(MFD *user,char filename[],bool fileprotect[3],int filelength)
{
if(user->maxfile==10)
{
cout<<"文件数量已达到上限!"<<endl;
return false;
}
UFD *ufd;
ufd = (UFD*)malloc(sizeof(UFD));
if(ufd == NULL)
{
return false;
}
strcpy(ufd->filename,filename);//进行文件的初始化
ufd->fileprotect[0] = fileprotect[0];
ufd->fileprotect[1] = fileprotect[1];
ufd->fileprotect[2] = fileprotect[2];
ufd->filelength = filelength;
ufd->read = ufd->write = 0;
ufd->next = NULL;
if(user->ufd == NULL)
{
user->ufd = ufd;
}
else
{
UFD *op ,*preOp = NULL;
op = user->ufd;
while(op)//查找是否存在同名文件
{
if(strcmp(op->filename,ufd->filename) == 0)
{
cout<<"文件 "<<ufd->filename<<" 已存在!"<<endl;
return false;
}
preOp = op;
op = op->next;
}
preOp->next = ufd;
user->maxfile++;//文件数加一
}
return true;
}
void displayUserFile(MFD *user)
{
cout<<"用户 "<<user->userName<<" 的文件列表:"<<endl;
UFD *ufd = NULL;
ufd = user->ufd;
while(ufd)
{
cout<<ufd->filename<<" "<<ufd->fileprotect[0]<<" "<<ufd->fileprotect[1]<<" "<<ufd->fileprotect[2]<<" "<<ufd->filelength<<endl;
ufd = ufd->next;
}
}
bool deleteFile(MFD *user,char filename[],AFD *afd)
{
UFD *ufd = NULL,*prefile = NULL,*temp;
ufd = afd->head;
while(ufd)//在打开文件中查找
{
if(strcmp(filename,ufd->filename) == 0)
{
cout<<"文件\""<<filename<<"\" 处于打开状态,请先关闭!\n";
return false;
}
ufd = ufd->next;
}
ufd = user->ufd;
while(ufd)//在文件中进行查找
{
if(strcmp(filename,ufd->filename) == 0)
{
if(ufd == user->ufd)
{
temp = ufd;
user->ufd = ufd->next;
}
else
{
temp = ufd;
prefile->next = ufd->next;
}
delete temp;
cout<<"文件删除成功!"<<endl;
return true;
}
prefile = ufd;
ufd = ufd->next;
}
if(prefile->next == NULL)
{
cout<<"用户 "<<user->userName<<" 没有此文件:\""<<filename<<"\"!"<<endl;
}
return false;
}
bool openFile(MFD *user,char filename[],AFD *afd,bool openprotect[])
{
UFD *ufd = NULL;
ufd = user->ufd;
while(ufd)
{
if(strcmp(ufd->filename,filename) == 0)
{
break;
}
ufd = ufd->next;
}
if(ufd)
{
UFD *xfile;
xfile = (UFD*)malloc(sizeof(UFD));
if(xfile == NULL)
{
return false;
}
*xfile = *ufd;//根据文件的权限进行打开权限的赋值
if(xfile->fileprotect[0]==0 || openprotect[0]==0)//当文件权限读为0或者打开权限读为0都视为没有打开权限
{
cout<<"没有读取权限!"<<endl;
return false;
}
else xfile->openprotect[0] = 1;//可读
//此时不管写和执行的权限是什么都不影响打开,因为后面判断权限用的是打开权限,所以我们要赋值
if(xfile->fileprotect[1] < openprotect[1])cout<<"没有写入权限!"<<endl;
if(xfile->fileprotect[2] < openprotect[2])cout<<"没有执行权限!"<<endl;
xfile->openprotect[1]=min(xfile->fileprotect[1],openprotect[1]);//选择权限小的写入
xfile->openprotect[2]=min(xfile->fileprotect[2],openprotect[2]);//!这个文件的一级保护码和二级保护码合并保护操作
xfile->next = NULL;
if(afd->head == NULL)
{
afd->head = afd->tail = xfile;
afd->currentopen += 1;
}
else if(afd->currentopen < afd->maxopen)
{
afd->tail->next = xfile;
afd->tail = xfile;
afd->currentopen += 1;
}
else
{
cout<<"文件打开数已达到上限!" <<endl;
return false;
}
}
else
{
cout<<"文件 "<<filename<<" 不存在!"<<endl;
return false;
}
return true;
}
bool closeFile(AFD *afd,char filename[])
{
UFD *ufd = NULL ,*preFile = NULL ,*temp = NULL;
ufd = afd->head;//在打开文件链表中进行查找
while(ufd)
{
if(strcmp(ufd->filename,filename) == 0)
{
if(ufd == afd->head)
{
if(ufd == afd->tail)
{
temp = ufd;
afd->head = afd->tail = NULL;
}
else
{
temp = ufd;
afd->head = ufd->next;
}
}
else if(ufd == afd->tail)
{
temp = ufd;
preFile->next = NULL;
afd->tail = preFile;
}
else
{
temp =ufd;
preFile->next = ufd->next;
}
delete temp;
cout<<"文件已关闭!"<<endl;
return true;
}
preFile = ufd;
ufd = ufd->next;
}
cout<<"该文件不存在!"<<endl;
return false;
}
bool readFile(AFD *afd,char filename[])
{
UFD *ufd = NULL;
ufd = afd->head;
while(ufd)
{
if(strcmp(ufd->filename,filename) == 0)
{
if(ufd->openprotect[1])
{
ufd->read++;
return true;
}
else
{
cout<<"没有执行权限!"<<endl;
return false;
}
}
ufd = ufd->next;
}
cout<<"没有此文件!"<<endl;
return false;
}
bool writeFile(AFD *afd,char filename[])
{
UFD *ufd = NULL;
ufd = afd->head;
while(ufd)
{
if(strcmp(ufd->filename,filename) == 0)
{
if(ufd->openprotect[2])
{
ufd->write++;
return true;
}
else
{
cout<<"没有写入权限!"<<endl;
return false;
}
}
ufd = ufd->next;
}
cout<<"没有此文件!"<<endl;
return false;
}
void displayOpenFile(AFD *afd,MFD *user)
{
cout<<"用户 "<<user->userName<<" 的文件打开列表:"<<endl;
UFD *ufd;
ufd = afd->head;
while(ufd)
{
cout<<ufd->filename<<" "<<ufd->openprotect[0]<<" "<<ufd->openprotect[1]<<" "<<ufd->openprotect[2]<<" "<<ufd->filelength<<" ";
cout<<" 执行次数:"<<ufd->read<<" 写入次数:"<<ufd->write<<endl;
ufd = ufd->next;
}
}