1.实验目的
①阅读并调试一个简单的文件系统,模拟文件管理的工作过程。从而对各种文件操作进行命令的实质内容和执行过程有比较深入的了解。
②了解设计一个n个用户的文件系统,每个用户可以保存M个文件。用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有creat、delete、open、close、read、write等命令。
2.实验分析
该文件系统是一个多用户、多任务的文件系统。对用户和用户的文件数目并没有上限。也就是说,该系统允许任何用户申请空间,而且在目录下的文件数目并不做任何限制。
3.源程序
/********************************************************
* 文件名:Simple_file_system.cpp
* 功能:简单文件管理系统模拟程序
*********************************************************/
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "conio.h"
#include<dos.h>
#define NULL 0
#define keynum 10
#define getspace(type) (type *)malloc(sizeof(type))
char cmd[64];
char buffer[36];
char user[32];
typedef char ALFA[12];
ALFA KWORD[keynum];
//-------------------------------------------------------
struct UFD{
char filename[32];
int safecode;
long length;
} * curfile = NULL;
//-------------------------------------------------------
struct MFD{
char username[32];
bool filepoint;
} * curuser = NULL,*elseuser=NULL;
typedef UFD UFD;
typedef MFD MFD;
int main();
//---------------------------------------------------------
void KeyWord()
{
strcpy(KWORD[1],"bye");
strcpy(KWORD[3],"close");
strcpy(KWORD[5],"delete");
strcpy(KWORD[7],"open");
strcpy(KWORD[9],"write");
}
//----------------------------------------------------------
int LoginDisplay()
{
int SELETE_1 = 0;
do
{
std::cout<<" *****请选择操作*****\n1.用户登录 2.用户注册 0.退出"<<std::endl;
std::cin>>SELETE_1;
}while(SELETE_1<0 || SELETE_1>2);
system("cls");
return SELETE_1;
}
//---------------------------------------------------------
bool Login(int SELETE)
{
FILE *fp, *fp1, *fp2;
char name[12];
switch(SELETE)
{
case 1:
if ((fp = fopen("LOGIN.exe", "rb")) == NULL)
{
std:: cout<<"\n 错误:不能打开登录文件。"<<std::endl;
getch();system("cls");
return false;
}
curuser = getspace(MFD);
std:: cout<<"\n *****登录***** \n用户名:";
std::cin>>name;
while(!feof(fp))
{
fread(curuser,sizeof(MFD),1,fp);
if(strcmp(curuser->username,name)==0)
break;
}
if(feof(fp))
{
std:: cout<<"\n 错误:该用户不存在。"<<std::endl;
fclose(fp);
return false;
}
else
{
fclose(fp);
return true;
}
break;
case 2:
if((fp=fopen("LOGIN.exe","ab"))==NULL)
fp=fopen("LOGIN.exe","wb+");
char name[12];
curuser = getspace(MFD);
while(1)
{
std::cout<<"\n *****新用户注册*****"<<std::endl;
std::cout<<"用户名:";
std::cin>>name;
fp1=fopen("LOGIN.exe","rb");
while(!feof(fp1))
{
fread(curuser,sizeof(MFD),1,fp1);
if(strcmp(curuser->username,name) ==0)
{
std::cout<<"\n该用户已经存在,请重新输入!"<<std::endl;
getch();
break;
}
}
if(feof(fp1))
{
strcpy(curuser->username,name);
curuser->filepoint=NULL;
fwrite(curuser,sizeof(MFD),1,fp);
strcpy(user,curuser->username);
strcat(user,".exe");
fp2=fopen(user,"wb+");
fclose(fp2);
std::cout<<"\n注册成功!"<<std::endl;
fclose(fp1);
fclose(fp);
break;
}
}
fp=fopen("LOGIN.exe","rb");
while(1)
{
fread(curuser,sizeof(MFD),1,fp);
if(feof(fp))
break;
std::cout<<curuser->username<<std::endl;
getch();
}
fclose(fp);
return true;
break;
default:
return false;
break;
}
}
//------------------------------------------------------------
void DisplayUFD()
{
if(curuser->filepoint == false)
std::cout<<"\n用户"<<curuser->username<<" 文件夹是空的"<<std::endl;
else
{
FILE * fp;
char filename[12];
strcpy(filename,curuser->username);
strcat(filename,".exe");
if((fp=fopen(filename,"rb"))==NULL)
{
std::cout<<"\n无法打开用户:"<<curuser->username<<" 的文件!"<<std::endl;
getch();
return;
}
else
{
std::cout<<"用户:"<<curuser->username<<"目录下的文件:"<<std::endl;
UFD * ufd;
int i=0;
ufd=getspace(UFD);
while(1)
{
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp))
break;
else
std::cout<<ufd->filename<<"\t"<<ufd->length<<"\t"<<ufd->safecode<<std::endl;
}
}
fclose(fp);
}
}
//--------------------------------------------------------------
void ByeFile(bool BOOL)
{
FILE * infile, * outfile;
char out[50];
strcpy(out,"outfilelocate.exe");
if((infile=fopen("LOGIN.exe","rb"))==NULL)
{
std::cout<<"\n保存错误。";
return;
}
else
{
if((outfile=fopen(out,"wb+"))==NULL)
//存放用户更新后的全部信息
{
std::cout<<"\n保存错误。";
fclose(infile);return;
}
else
{
MFD * mfd=getspace(MFD);
while(1)
{
fread(mfd,sizeof(MFD),1,infile);
if(feof(infile))
break;
if((strcmp(mfd->username,curuser->username))==0)
{
if(BOOL)
fwrite(curuser,sizeof(MFD),1,outfile);
else continue;
}
else
fwrite(mfd,sizeof(MFD),1,outfile);
}
fclose(infile);fclose(outfile);
remove("LOGIN.exe");
rename(out,"LOGIN.exe");
}
}
}
//--------------------------------------------------------------
bool ClearUserFile()
{
FILE * fp;
char file[50];
strcpy(file,curuser->username);
strcat(file,".exe");
if((fp=fopen(file,"rb"))==NULL)
{
//fclose(fp);
std::cout<<"\n该用户不存在!";return true;
}
else
{
UFD * ufd=getspace(UFD);
while(1)
{
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp))
break;
else
remove(ufd->filename);
}
fclose(fp);
return true;
}
}
//------------------------------------------------------------
void ClearUserMes()
{
char name[50];
strcpy(name,curuser->username);
strcat(name,".exe");
remove(name);
ByeFile(false);
}
//------------------------------------------------------------
void DeleteUser()
{
char ch;
std::cout<<"\n该操作将会是你在系统所有信息删除,下次登录时你必须重新申请用户名!"<<std::endl;
std::cout<<"\n你确定要删除你在系统中的注册信息吗? Y/N"<<std::endl;
std::cin>>ch;
switch(ch)
{
case'Y':
case 'y':
if(ClearUserFile())
ClearUserMes();
break;
default:
std::cout<<"\n你取消了此操作!";
break;
}
}
//-------------------------------------------------------------
void CreatFile()
{
FILE * fp;
curuser->filepoint=true;
if((fp=fopen(buffer,"r"))==NULL)
{
if((fp=fopen(buffer,"w"))==NULL)
{
std::cout<<"\n创建文件失败!";
//fclose(fp);
return;
}
fclose(fp);
}
else
{
std::cout<<"\n该文件已经存在,创建另一个文件? Y/N";
char ch;
std::cin>>ch;
switch(ch)
{
case'Y':
case'y':
std::cout<<"\n输入新文件名:";
std::cin>>buffer;
strcat(buffer,".txt");
fclose(fp);
if((fp=fopen(buffer,"w"))==NULL)
{
std::cout<<"\n创建文件失败!";
//fclose(fp);
return;
}
fclose(fp);
break;
default:
fclose(fp);
return;
}
}
strcpy(user,curuser->username);
strcat(user,".exe");
curfile = getspace(UFD);
strcpy(curfile->filename,buffer);
curfile->length=0;
curfile->safecode=30;
if((fp=fopen(user,"ab"))==NULL)
{
std::cout<<"\n错误:你可能不是合法用户。"<<std::endl;
getch();
}
else
{
fwrite(curfile,sizeof(UFD),1,fp);
std::cout<<"\n文件"<<curfile->filename<<" 创建成功!";
}
fclose(fp);
}
//---------------------------------------------------------------
void DeleteFile()
{
char ch;
FILE * infile, * outfile;
std::cout<<"\n确定要删除文件:"<<buffer<<" Y/N"<<std::endl;
std::cin>>ch;
switch(ch)
{
case'Y':
case'y':
char out[50],in[50];
strcpy(out,"outfilelocate.exe");
strcpy(in,curuser->username);
strcat(in,".exe");
if((infile=fopen(in,"rb"))==NULL)
{
std::cout<<"\n保存错误。";
//fclose(infile);
return;
}
else
{
if((outfile=fopen(out,"wb+"))==NULL)
{
std::cout<<"\n保存错误。";
fclose(infile);return;
}
else
{
UFD * ufd = getspace(UFD);
while(1)
{
fread(ufd,sizeof(UFD),1,infile);
if(feof(infile))
break;
if((strcmp(ufd->filename,buffer))==0)
continue;
else
fwrite(ufd,sizeof(UFD),1,outfile);
}
fclose(infile);fclose(outfile);
remove(in);
rename(out,in);
}
}
remove(buffer);
break;
default:
break;
}
}
//---------------------------------------------------------------
void ListAllFile()
{
DisplayUFD();
}
void WriteLengthToFile(int Len,bool BOOL);
//---------------------------------------------------------------
void OpenFile()
{
FILE * fp;
char ch;
int i=0;
system(buffer);
fp=fopen(buffer,"r");
while(1){
if(feof(fp))
break;
ch=fgetc(fp);
i++;
}
WriteLengthToFile(i,false);
}
//----------------------------------------------------------------
bool QueryModElse(bool BOOL,bool &flag)
{
FILE * fp;
char user[50];
UFD * ufd=getspace(UFD);
strcpy(user,elseuser->username);
strcat(user,".exe");
if((fp=fopen(user,"rb"))==NULL){
//fclose(fp);
std::cout<<"\n操作出现错误,对此我们表示歉意!";return false;
}
else{
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){
fclose(fp);return false;
}
if(strcmp(ufd->filename,buffer)==0){
if(BOOL)
{
if(ufd->safecode==31 || ufd->safecode==33)
return true;
else{
std::cout<<"\n你无权对文件"<<buffer<<"执行此操作!";
flag=true;return false;}
}
else
{
if(ufd->safecode ==32 || ufd->safecode ==33)
return true;
else{
std::cout<<"\n你无权对文件"<<buffer<<"执行此操作!";
flag=true;return false;}
}
}
}
}
}
//-----------------------------------------------------------------------
bool QueryMod(bool BOOL)
{
FILE *fp,*fp1;
bool flag=false;
char user[50];
UFD * ufd= getspace(UFD);
strcpy(user,curuser->username);
strcat(user,".exe");
if((fp=fopen(user,"rb"))==NULL){
//fclose(fp);
std::cout<<"\n操作出现错误,对此我们表示歉意!";return false;
}
else{
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){
fclose(fp);
fp1=fopen("LOGIN.exe","rb");
elseuser = getspace(MFD);
bool BOOL_1=false;
while(1){
fread(elseuser,sizeof(MFD),1,fp1);
if(feof(fp1) && ! BOOL_1)
return false;
if(elseuser != curuser){
if((BOOL_1==QueryModElse(BOOL,flag)))
return true;
if(flag)
return false;
}
}
}
if(strcmp(ufd->filename,buffer)==0){
fclose(fp);return true;
}
}
}
}
//---------------------------------------------------------------
bool WriteRight(int len,bool BOOL)
{
char user[50],outfile[50];
FILE * fp,*fp1;
strcpy(user,elseuser->username);
strcat(user,".exe");
if((fp=fopen(user,"rb"))==NULL){
//fclose(fp);
return false;
}
else{
UFD * ufd = getspace(UFD);
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){
fclose(fp);return false;
}
if((strcmp(ufd->filename,buffer))==0){
strcpy(outfile,"outfilelocate.exe");
if((fp1=fopen(outfile,"wb+"))==NULL){
std::cout<<"\n错误:写入文件长度出错_3。";
//fclose(fp1);
fclose(fp);return false;
}
else{
fclose(fp);
fp=fopen(user,"rb");
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp))
break;
if(strcmp(ufd->filename,buffer)==0){
if(BOOL) ufd->length+=len;
else ufd->length =len;
}
fwrite(ufd,sizeof(UFD),1,fp1);
}
fclose(fp);fclose(fp1);
remove(user);
rename(outfile,user);
return true;
}
}
}
}
}
//----------------------------------------------------------------------
void WriteLengthToFile(int Len,bool BOOL)
{
FILE * fp;
if((fp=fopen("LOGIN.exe","rb"))==NULL){
std::cout<<"\n写入文件长度错误_1!";
//fclose(fp);
return;
}
else{
elseuser=getspace(MFD);
while(1){
fread(elseuser,sizeof(MFD),1,fp);
if(feof(fp))
break;
else{
if(WriteRight(Len,BOOL)){
fclose(fp);return;
}
}
}
std::cout<<"\n写入文件长度错误_2!";
fclose(fp);return;
}
}
//------------------------------------------------------------------
void WriteFile()
{
if(!QueryMod(true))
return;
char ch;
int i=0;
FILE * fp;
if((fp=fopen(buffer,"r"))==NULL)
{
std::cout<<"\n该文件不存在,请创建该文件后再写入。";
//fclose(fp);
return;
}
fclose(fp);
std::cout<<"\n请选择写入方式:"<<std::endl;
std::cout<<" 1.覆盖原文件 2.在原文件末尾写入 3.取消"<<std::endl;
std::cin >> ch;
std::cout<<"开始输入正文:"<<std::endl;
switch(ch)
{
case '1':
if((fp=fopen(buffer,"w"))==NULL)
std::cout<<"\n文件打开失败。";
else
{
ch=getchar();
while(ch!='#')
{
i++;
fputc(ch,fp);
ch=getchar();
}
}
fclose(fp);
WriteLengthToFile(i,false);
break;
case '2':
if((fp=fopen(buffer,"a"))==NULL)
std::cout<<"\n文件打开失败。";
else
{
ch=getchar();
while(ch!='#')
{
i++;
fputc(ch,fp);
ch=getchar();
}
}
fclose(fp);
WriteLengthToFile(i,true);
break;
default:
break;
}
}
//------------------------------------------------------------------
void ReadFile()
{
if(!QueryMod(false))
return;
FILE * fp;
if((fp=fopen(buffer,"r"))==NULL)
{
std::cout<<buffer;
std::cout<<"\n该文件不存在。";
return;
}
else{
char ch;
ch=fgetc(fp);
while(ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
std::cout<<std::endl;
}
fclose(fp);
}
//-----------------------------------------------------------------
void ChangeMod()
{
int mod=40;
FILE * fp,* infile, * outfile;
char in[50],out[50];
UFD * ufd = getspace(UFD);
strcpy(in,curuser->username);
strcat(in,".exe");
strcpy(out,"outfilelocate.exe");
if((fp=fopen(in,"rb"))==NULL){
//fclose(fp);
std::cout<<"\n操作出现错误,对此我们表示歉意!";
return;
}
else{
while(1){
fread(ufd,sizeof(UFD),1,fp);
if(feof(fp)){
std::cout<<"\n你没有权限对文件"<<buffer<<"执行该操作!";
fclose(fp);return;
}
if(strcmp(ufd->filename,buffer)==0){
fclose(fp);break;
}
}
}
bool flag1=true;
while(flag1)
{
std::cout<<"\n输入文件 "<<buffer<<"的新的权限值:";
std::cin>>mod;
if(mod<30 || mod>33)
{
std::cout<<"\n错误:权限值必须在30~33之间";
continue;
}
else{
char ch;
switch(mod){
case 30:
std::cout<<"\n当前权限设置:其他用户对"<<buffer<<"既没读权也没写权!";
break;
case 31:
std::cout<<"\n当前权限设置:其他用户对"<<buffer<<"没读权但有写权!";
break;
case 32:
std::cout<<"\n当前权限设置:其他用户对"<<buffer<<"有读权但没写权!";
break;
case 33:
std::cout<<"\n当前权限设置:其他用户对"<<buffer<<"既有读权也有写权!";
break;
default: break;
}
std::cout<<"\n确认按Y键,取消按N键";
std::cin>>ch;
switch(ch){
case 'Y':
case 'y':flag1=false;break;
default:flag1=true;
}
}
}
if((infile=fopen(in,"rb"))==NULL){
std::cout<<"\n操作出现错误,对此我们表示歉意!";fclose(infile);
return;
}
else{
if((outfile=fopen(out,"wb+"))==NULL){
std::cout<<"\n操作出现错误,对此我们表示歉意!";
fclose(infile);//fclose(outfile);
return;
}
else{
while(1)
{
fread(ufd,sizeof(UFD),1,infile);
if(feof(infile))
break;
if((strcmp(ufd->filename,buffer))==0)
ufd->safecode=mod;
fwrite(ufd,sizeof(UFD),1,outfile);
}
fclose(infile);fclose(outfile);
remove(in);
rename(out,in);
}
}
}
//------------------------------------------------------------------------
void Execute(int i,int len,int cmdset)
{
int j=0;
for(;i<len;i++)
{
if(cmd[i]=='>' || cmd[i]==' '){
//buffer[i] ='\0';
break;
}
/* if(i==len-1)
*
{
buffer[j]=cmd[i];
buffer[j+1]='\0';
break;
} */
buffer[j]=cmd[i];j++;
}
buffer[j]='\0';
strcat(buffer,".txt");
switch(cmdset)
{
case 1:
ByeFile(true);
system("cls");
break;
case 2:
if((strcmp(buffer,".txt"))==0){
std::cout<<"\n输入命令出错!";
return;
}
ChangeMod();
break;
case 3:
DeleteUser();
break;
case 4:
if((strcmp(buffer,".txt"))==0){
std::cout<<"\n输入命令出错!";
return;
}
CreatFile();
break;
case 5:
if((strcmp(buffer,".txt"))==0){
std::cout<<"\n输入命令出错!";
return;
}
DeleteFile();
break;
case 6:
ListAllFile();
break;
case 7:
if((strcmp(buffer,".txt"))==0){
std::cout<<"\n输入命令出错!";
return;
}
OpenFile();
break;
case 8:
if((strcmp(buffer,".txt"))==0){
std::cout<<"\n输入命令出错!";
return;
}
ReadFile();
break;
case 9:
if((strcmp(buffer,".txt"))==0){
std::cout<<"\n输入命令出错!";
return;
}
WriteFile();
break;
default:
break;
}
}
//----------------------------------------------------------------------
void Command()
{
int len=0,i,j;
int cmdset;
while(1)
{
cmdset = 0;
std::cout<<"\nrun\\";
std::cin>>cmd;
len = strlen(cmd);
i=0;j=0;
while(cmd[i]=='>' || cmd[i]==' '){i++;}
for(;i<len;i++)
{
if(cmd[i]=='>'|| cmd[i]==' ' || i==len-1)
{
if(cmd[i]=='>' || cmd[i]==' ')
buffer[j]='\0';
else
if(i==len-1)
{
buffer[j]=cmd[i];
buffer[j+1]='\0';
}
i++;
j=0;
int low=1,mid,high=keynum-1;
bool BOOL=false;
while(low<=high){
mid=(low+high)/2;
if(strcmp(buffer,KWORD[mid])<=0)high=mid-1;
if(strcmp(buffer,KWORD[mid])>=0)low=mid+1;
if(strcmp(buffer,KWORD[mid])==0){
BOOL=true;
break;
}
}
if(!BOOL)
{
std::cout<<"\n"<<buffer<<"不是系统定义的命令";
cmdset=0;break;
}
else{cmdset=mid;break;}
}
else{
buffer[j]=cmd[i];
j++;
}
}
if(cmdset==0)continue;
while(cmd[i]=='>'||cmd[i]==' '){i++;}
buffer[0]='\0';
Execute(i,len,cmdset);
}
}
//----------------------------------------------------------------------
int main()
{
while(1){
int SELETE=LoginDisplay();
if(SELETE==0)
exit(0);
bool BOOL=Login(SELETE);
if(BOOL)
{
KeyWord();
DisplayUFD();
Command();
}
}
}