操作系统实训C++文件管理系统.docx
《操作系统实训C++文件管理系统.docx》由会员分享,可在线阅读,更多相关《操作系统实训C++文件管理系统.docx(27页珍藏版)》请在冰点文库上搜索。
操作系统实训C++文件管理系统
1设计目的(用小3号黑体,并留出上下间距为:
段前0.5行,段后0.5行)
《操作系统概论》学习已经快结束了,通过本课程,了解了操作系统的发展,组成,处理器管理,存储管理,文件管理,设备管理,并发进程等相关知识。
理论必须与实际联系,才能理解的更加深刻,所以进行了这次课程设计,制作一个文件模拟系统的程序,加深对相关知识的理解与运用。
2设计内容
本设计应完成以下要求:
1.设计一个10个用户的文件系统,用户至少有Create、delete、open、close、read、write等文件操作命令。
2.程序采用多级文件目录管理,仅可能模拟文件存取的全过程。
3设计步骤
3.1开发平台
3.1.1开发环境介绍
我们采用了C语言来并在VisualStudio2005平台实现。
.NETFramework是生成、运行下一代应用程序和XMLWebServices的内部Windows组件。
它简化了分布式Internet环境中的应用程序开发,由公共语言运行库(CLR)和.NETFramework类库两个组件构成。
VisualStudio2005是微软公司开发的集成开发环境,支持C、C++、VB、J#、C#等多种开发语言,界面友好,并有自动补全代码功能,便于调式,是当前最流行的.NETFramework开发工具。
安装VisualStudio2005的系统要求:
硬件需求
描述
处理器
Pentium3级600MHZ以上处理器
RAM
WindowsXPProfessional至少为160MB
硬盘
对于VisualC#.NET、VisualBasic.NET,需要600MB硬盘空间,安装驱动器上需要1.5GB磁盘空间
视频
800*600像素,256色(建议:
增强色16位)
鼠标
Microsoft鼠标或兼容的指针设备
3.1.2开发界面截图
3.2详细设计
3.2.1算法说明
用户登录时要输入用户名和密码,如果正确则进入初始界面,默认只有十个用户。
用户登录成功后,可以使用的命令列表如下(命令不区分大小写):
Create:
创建一个新的文件;如果文件名空,则提示出错;
Open:
打开一个已经存在的文件;如果该文件不存在,则提示出错;
Read:
读取目标文件中的内容;如果目标文件不存在,则提示出错;
Write:
向目标文件写入内容;如果目标文件不存在,则提示出错;
Delete:
删除目标文件;如果目标文件不存在,则提示出错;
Mkdir:
创建一个新的文件夹;如果目录名空,则提示出错;
Cd:
改变当前路径,转到目标目录下;入股目标目录不存在,则提示出错;
Dir:
列出当前目录下文件;
Copy:
把文件或目录由源地址拷贝到目标地址;
Logout:
推出文件管理系统;
文件目录的检索使用了简单的线性搜索,文件保护简单使用了三位保护码:
允许读写执行、对应位为1,对应位为0,则表示不允许读写、执行。
体现在工程开发中,我们建立了头文件:
myHead.h,用以存放程序中用到的结构体定义和全局变量定义;代码主文件:
myFileSys.cpp,存放程序主要代码。
程序中使用的主要设计结构如下:
1.一个文件索引结构
typedefstruct
{
unsignedIndex;//文件元素索引编号
charFileName[MAXFILENAMELEN];//文件元素名
charParentName[MAXFILENAMELEN];//父节点名
unsignedFileBlockId;//文件元素所在物理块编号
unsignedFileLevel;//文件元素所在层次,层+文件元素名为一个文件元素的逻辑位置
unsignedeffect;//是否有效,-无效,-有效
}FileIndexElement;
2、文件状态结构
typedefenum
{
closed,//已被关闭
opened,//已被打开
reading,//正在被读取
writing//正在被写入
}FileStatus;
3、文件系统中的元素结构,包括文件和文件夹
typedefstructfse
{
structfse*parent;//指向自己的父亲节点
unsignedFileLevel;//文件元素所在层次,层+文件元素名为一个文件元素的逻辑位置
charFileName[MAXFILENAMELEN];//文件元素名
unsignedFileBlockId;//文件元素所在物理块编号
unsignedFileElemLen;//文件元素的长度
FETypeType;//文件元素类型
FEAccessAccess;//文件元素可供操作的权限
UserCreator;//文件创建者
charCreateTime[18];//创建时间,日期格式:
MM/DD/YYHH:
MI:
SS
charLastModTime[18];//最后一次修改时间
char*FileData;//一个文件的数据开始地址,文件夹时该值为NULL
FileStatusfileStu;//如果是一个文件表示文件当前的状态
}FSElement;
3.2.2系统流程图
3.3运行与测试
3.3.1运行测试
运行Debug目录下的myFileSys.exe可执行文件,运行成功,显示欢迎界面并帮助信息,如下图:
系统默认了十个普通用户:
user1,user2,user3,user4,user5,user6,user7,user8,user9,user10。
所有用户密码与其用户名相同。
输入正确的用户名和密码,单击回车键就可以进入文件模拟系统,以用户user1为例,下面显示user1登录成功,如下图:
用create命令创建test文件夹,用cd命令进入test文件夹,如下图:
用create命令创建三个文件:
1.txt,2.txt,3.txt。
用dir命令列出当前目录下文件和文件夹如下:
用open命令打开1.txt文件,用write命令写入信息,用close命令关闭1.txt文件。
用logout命令退出系统,界面如下:
运行测试表明,正常输入各项操作指令后,程序均正常运行并显示出预期结果,程序运行成功。
3.3.2异常处理测试
键入错误的用户名或者错误的密码后,登陆失败并提示重新输入,如下图:
用cd命令进入一个不存在文件夹发生错误,界面如下:
删除一个不存在的文件而发生错误,界面如下:
文件没有打开的情况下,使用read命令读取或者使用write命令写入导致错误,界面如下:
在上面的异常测试中,输入非法的指令后,系统能辨别并能给出相应的出错提示信息,表明系统具有一定的健壮性。
3.4使用说明
1、双击debug文件夹中的myFileSys.exe可执行程序,启动模拟界面。
2、输入用户名和密码,单击回车键,如果通过验证,则进入系统。
3、输入createbooks命令,可以建立一个名为books的文件夹。
输入create1.txt命令可以创建一个名为1.txt的文本文件(文件名和文件夹名字随意)。
4、创建的文件夹和文件可以通过dir命令在当前目录下面显示出来。
5、输入open1.txt命令,可以打开1.txt文本文件,只有打开的文件才能写入数据。
6、输入write1.txt命令。
可以在1.txt文件中写入数据,例如写入:
mynameis
Zheng!
按ctrl+D可以保存输入的信息。
7、输入read1.txt命令,可以查看该文件中的信息。
8、输入close1.txt命令,则可以关闭该文件
9、输入cdbooks命令,可以进入books文件夹。
10、输入logout,则注销当前用户了。
4设计总结
本文件系统中,用户可以用到的指令包括:
"create","open","read","write","close","delete","cd","dir","logout","copy"等十一个文件操作指令,实现了基本的文件管理的相关功能。
通过这次课程设计。
对VisualStudio2005和.NETFramework有了进一步的了解,熟悉了相关软件和技术的使用。
在设计要求中,只要完成10个用户模拟,并对文件结构作了简化,我们对此作了扩充,除了默认用户10个和1个特权用户,每个用户创建文件数目没有限制,文件的模拟也是从底层的块开始。
我做的这个文件管理模拟系统还存在一些不足:
控制台形式的界面,对用户来说不够友好,应当继续开发出窗体界面。
程序代码还有锤炼的空间,可以进一步进行研究,增加代码的执行效率,提升程序的功能。
通过本课程设计的课题研究、资料查询、代码编写、调试运行、测试总结等过程的进行,使自己对计算机操作系统的文件系统的管理方式有了进一步的理解,加深了对文件系统的工作原理的认识,使理论知识更加巩固。
5附录
全局变量声明:
constunsignedFILESYSCAP=1024*1024;//模拟文件系统的容量设为M
constunsignedBITMAPLEN=64;//位示图的长度
constunsignedFILEBLOCKCAP=512;//一个文件块的大小
constunsignedFILEBLOCKCOU=512;//文件系统中文件块的数量
constunsignedMAXFILENAMELEN=11;//最长文件名的长度
constunsignedMAXPASSWORDLEN=11;//用户密码的最大长度
constunsignedUSERTESTLOGINCOU=5;//用户登录尝试次数
constunsignedCOMMANDMAXLEN=200;//命令行最大长度
constunsignedPROSETCOMMCOU=11;//预设命令数
constchar*PROSETCOMM[]={"create","open","read","write","close","delete","mkdir","cd","dir","logout","copy"};
创建文件函数:
FSElement*CreateFileElement()实现:
voidCreate(char*filename)
{
if(strcmp(filename,"")==0)
{
printf("对不起,文件名不能为空。
\n");
}
else
{
CreateFileElement(protect,filename,file,NULL,CS.CurrParent);
}
printf("%s%s\n$",CS.CurrentUser.UserName,CS.CurrentPath);
初始化文件系统函数:
InitFileSys()实现:
{
//初始化模拟的文件系统
if((FS.FSStart=(char*)malloc(FILESYSCAP))==NULL)
{
returnfalse;
}
FS.FileSystemCap=FILESYSCAP;
FS.bm.BitMapLen=BITMAPLEN;
FS.bm.BMStart=FS.FSStart;
//设置位示图为未使用
memset(FS.bm.BMStart,'\0',FS.bm.BitMapLen);
//初始化文件系统索引
FS.FI.FIStart=(FileIndexElement*)(FS.FSStart+BITMAPLEN);
//因为是模拟系统,暂定一个文件或文件夹最多占用一个文件块,一个文件块只放一个文件元素
FS.FI.FILen=sizeof(FileIndexElement)*FILEBLOCKCOU+sizeof(unsigned)*2;
FS.FI.FICount=0;
memset(FS.FI.FIStart,'\0',FS.FI.FILen);
//初始化文件块
FS.FileBlockCou=FILEBLOCKCOU;
FS.head=CreateFileBlockList((FS.FSStart+FILESYSCAP-FILEBLOCKCAP*FILEBLOCKCOU),
FILEBLOCKCAP,FS.FileBlockCou);//区域的后FILEBLOCKCAP*FILEBLOCKCOU个单元用来存储数据
if(FS.head==NULL)
{
returnfalse;
}
//初始化系统当前状态
CS.CurrentUser.UserName=(char*)calloc(10,sizeof(char));
strcpy(CS.CurrentUser.UserName,"man");
CS.CurrentUser.ut=admin;
CS.CurrParent=NULL;
CS.FileLevel=0;
CS.CurrentPath=(char*)calloc(1000,sizeof(char));
//创建一个根目录
base=CreateFileElement(pub,"root",dir,NULL,NULL);
if(base==NULL)
{
returnfalse;
}
else
{
returntrue;
}
}
登录验证函数:
Login()实现如下:
{
charusername[10];
charpassword[MAXPASSWORDLEN];
intc;
for(c=0;c{
inti=0;
memset(password,'\0',MAXPASSWORDLEN);
memset(username,'\0',10);
printf("请输入用户名:
");
gets(username);
printf("请输入密码:
");
while(i=0x0d){};
password[strlen(password)-1]='\0';
printf("\nusername:
%s\npassword:
%s\n",username,password);
if((strcmp(username,"user1")==0&&strcmp(password,"user1")==0)||
(strcmp(username,"user2")==0&&strcmp(password,"user2")==0)||
(strcmp(username,"user3")==0&&strcmp(password,"user3")==0)||
(strcmp(username,"user4")==0&&strcmp(password,"user4")==0)||
(strcmp(username,"user5")==0&&strcmp(password,"user5")==0)||
(strcmp(username,"user6")==0&&strcmp(password,"user6")==0)||
(strcmp(username,"user7")==0&&strcmp(password,"user7")==0)||
(strcmp(username,"user8")==0&&strcmp(password,"user8")==0)||
(strcmp(username,"user9")==0&&strcmp(password,"user9")==0)||
(strcmp(username,"user10")==0&&strcmp(password,"user10")==0)||
(strcmp(username,"cafuc")==0&&strcmp(password,"cafuc")==0))
{
if(strcmp(username,"cafuc")==0)//一个管理员
{
strcpy(CS.CurrentUser.UserName,username);
CS.CurrentUser.ut=admin;
}
else
{
strcpy(CS.CurrentUser.UserName,username);
CS.CurrentUser.ut=comm;
}
CS.FileLevel++;
CS.CurrParent=base;
strcpy(CS.CurrentPath,"\\");
printf("\n欢迎使用飞行学院文件模拟系统。
\n");
printf("\n%s%s\n$",username,CS.CurrentPath);
break;
}
else
{
printf("\n用户名或密码错误,请重新输入。
\n");
}
}
if(c>=USERTESTLOGINCOU)//非法用户
{
printf("\n对不起,您不是该系统用户,按任意键退出系统。
\n");
returnfalse;
}
else
{
returntrue;
}
}
列出当前目录的文件和文件夹函数:
Dir(char*path)实现如下:
{
chardisplay[1000];
memset(display,'\0',1000);
//查找显示内容
for(unsignedi=0;i{
if(strcmp(FS.FI.FIStart[i].ParentName,CS.CurrParent->FileName)==0&&
FS.FI.FIStart[i].FileLevel==CS.FileLevel&&FS.FI.FIStart[i].effect==1)
{
strcat(display,FS.FI.FIStart[i].FileName);
strcat(display,"\t\t");
}
}
printf("\n%s\n",display);
printf("%s%s\n$",CS.CurrentUser.UserName,CS.CurrentPath);
}
创建一个文件夹函数:
Mkdir(char*filename)实现如下:
{
if(strcmp(filename,"")==0)
{
printf("对不起,文件夹名不能为空。
\n");
}
else
{
CreateFileElement(protect,filename,dir,NULL,CS.CurrParent);
}
printf("%s%s\n$",CS.CurrentUser.UserName,CS.CurrentPath);
}
进入一个文件夹函数:
Cd(char*path)实现如下:
{
intsplitDisplayCou=0;//分割符出现的次数
if(strcmp(path,"..")==0)
{
if(CS.FileLevel>0)
{
CS.FileLevel--;
CS.CurrParent=CS.CurrParent->parent;
unsignedi;
for(i=strlen(CS.CurrentPath)-1;i>0;i--)
{
if(CS.CurrentPath[i]=='\\')
{
splitDisplayCou++;
if(splitDisplayCou==2)//已过滤掉最后一个目录名
{
break;
}
}
}
chartemppath[1000];
strcpy(temppath,CS.CurrentPath);
memset(CS.CurrentPath,'\0',1000);
strncpy(CS.CurrentPath,temppath,i+1);
}
else{}
}
else
{
chardisplay[100]="";
for(unsignedi=0;i{
if(strcmp(FS.FI.FIStart[i].ParentName,CS.CurrParent->FileName)==0&&
FS.FI.FIStart[i].FileLevel==CS.FileLevel&&FS.FI.FIStart[i].effect==1&&
strcmp(FS.FI.FIStart[i].FileName,path)==0)
{
strcpy(display,"文件存在。
\n");
CS.CurrParent=(FSElement*)FindBlankFileBlock(FS.FI.FIStart[i].FileBlockId);
CS.FileLevel++;
strcat(CS.CurrentPath,path);
strcat(CS.CurrentPath,"\\");
break;
}
}
if(strcmp(display,"")==0)//文件夹不存在,什么都不做
{
printf("当前目录下没有您要进入的文件夹。
\n");
}
}
printf("%s%s\n$",CS.CurrentUser.U