完整word版操作系统试验模拟文件管理系统word文档良心出品.docx
《完整word版操作系统试验模拟文件管理系统word文档良心出品.docx》由会员分享,可在线阅读,更多相关《完整word版操作系统试验模拟文件管理系统word文档良心出品.docx(17页珍藏版)》请在冰豆网上搜索。
完整word版操作系统试验模拟文件管理系统word文档良心出品
模拟文件管理系统
一、实验内容
1.基本要求:
编写一程序,模拟一个简单的文件管理系统。
树型结构,目录下可以是目录,也可以是文件。
在此文件管理系统,可实现的操作有:
改变目录:
格式:
cd<目录名>
显示目录:
格式:
dir[<目录名>]
创建目录:
格式:
md<目录名>
删除目录:
格式:
rd<目录名>
新建文件:
格式:
edit<文件名>
删除文件:
格式:
del<文件名>
退出文件系统:
exit
2.目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开
3.功能具体描述:
改变目录:
改变当前工作目录,目录不存在是给出出错信息
显示目录:
显示指定目录下或当前目录下所有文件和一级目录(选做:
带/s参数的dir命令,显示所有子目录)
创建目录:
在指定路径或当前路径下创建指定目录。
重名时给出出错信息。
删除目录:
删除指定目录下所有文件和子目录。
要删目录不空时,要给出提示是否要删除。
创建文件:
创建指定名字的文件,只要创建表示文件的节点即可,内容及大小不考虑。
删除文件:
删除指定文件,不存在时给出出错信息。
退出文件系统:
exit
4.总体流程:
初始化文件目录
输出提示符,等待接受命令,分析键入的命令;
对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令。
直到键入exit退出为止。
二、数据结构设计
StructFileNode
{
Charfilename[FILENAME_LEN];//文件名/目录名
Intisdir;//目录、文件的识别标志
Inti_nlink;//文件链接数
Intadr;//文件的地址
StructFileNode*parent,*child;//指向父亲的指针和左孩子的指针
StructFileNode*sibling_prev,*sibling_next;//指向前一个兄弟的指针和后一个兄弟的指针。
}
三、算法设计
3.1功能模块图
3.2算法思路
3.2.1实现方法
boolspile(char*str,char*cmdstr,char*filestr);//切割字符串
boolshell(char*str);//用来解释命令
boolerrorp(intid);//打印错误提示
boolboot();//启动初始化
filenode*find(char*str,filenode*_root);//递归对目录树进行查找
boolcdexc(char*str);//执行cd命令
booldirexc(char*str);//执行dir命令
boolmdexc(char*str);//执行md命令
booleditexc(char*str);//执行edit命令
booldelexc(char*str,filenode*fcur,boolmode,booldir);//执行del命令
boolexitexc();//退出
filenode*createnode(char*str,bool_isdir,int_adr,filenode*_par);//新建对象节点
函数调用图
3.2.2设计思想
建立一刻目录树,根据输入的命令字符串,对该目录树进行增删等操作。
(1)定义全局变量
filenode*cur=NULL;//指向当前目录节点
filenode*root=NULL;//指向根节点目录节点
char*shellstr[7]={"cd","dir","md","rd","edit","del","exit"};//命令字符串
intshelllen=7;//命令的字符串的长度
(2)主函数模块
调用boot模块初始化,然后使用while循环,每次循环中用户可以输入命令字符串,调用shell模块进行解释并执行操作,执行完成后再次进入循环,直到用户使用exit退出。
(3)其他模块说明(用文字描述,不要代码)
删除模块:
调用find函数查找到目录节点,然后进行删除节点操作,并注意特殊情况。
新建目录/文件模块:
通过调用find查找是否重复,若不重复就进行增加节点。
切换目录模块:
通过find函数找到节点,然后将cur指针指向该节点。
显示目录模块:
通过find函数找到节点,循环遍历该节点显示。
退出模块:
执行exit函数。
代码:
#include
#include
#include
#defineFILENAME_LEN256
#defineSHELL_LEN5
typedefenum{false,true}bool;
char*shellstr[7]={"cd","dir","md","rd","edit","del","exit"};
intshelllen=7;//命令的字符串的长度
typedefstructfilenode_i{//文件节点
charfilename[FILENAME_LEN];//文件名
boolisdir;//是否目录
inti_nlink;//文件连接数
intadr;//文件地址
structfilenode_i*par;//指向父节点
structfilenode_i*chi;//指向第一个孩子节点
structfilenode_i*pre;//指向上一个兄弟节点
structfilenode_i*nex;//指向下一个兄弟节点
}filenode;
filenode*cur=NULL;//指向当前目录
filenode*root=NULL;//指向根节点目录
boolspile(char*str,char*cmdstr,char*filestr);//切割字符串
boolshell(char*str);//用来解释命令
boolerrorp(intid);//打印错误提示
boolboot();//启动初始化
filenode*find(char*str,filenode*_root);//递归对目录树进行查找
boolcdexc(char*str);//执行cd命令
booldirexc(char*str);//执行dir命令
boolmdexc(char*str);//执行md命令
booleditexc(char*str);//执行edit命令
booldelexc(char*str,filenode*fcur,boolmode,booldir);//执行del命令
boolexitexc();//退出
filenode*createnode(char*str,bool_isdir,int_adr,filenode*_par);
main(){
charinputs[FILENAME_LEN]="";
boot();
errorp(6);
while
(1){
printf("\n>");
gets(inputs);
shell(inputs);
}
}
//下面进行函数的实现
//////////////////////////////////////////////////////////////////
//**************************************************************
////test
//test(){//这是用来对目录进行测试,在一开始建立目录结构
//filenode*p=createnode("hello",false,0,root);
//filenode*p2=NULL;
//root->i_nlink=2;
//root->chi=p;p->par=root;
//p2=createnode("hello2",true,0,root);
//p->nex=p2;p2->par=root;p2->pre=p;
//p2->i_nlink=2;
//p=createnode("hello2_1",true,0,p2);
//p2->chi=p;p->par=p2;
//p2=createnode("hello2_2",false,0,p->par);
//p->nex=p2;p2->par=p->par;p2->pre=p;
//}
boolspile(char*str,char*cmdstr,char*filestr){
charstrclo[FILENAME_LEN]="";
char*p=NULL;
strcpy(strclo,str);
p=strtok(strclo,"");//调用的strok进行分割
if(p==NULL)returnfalse;
strcpy(cmdstr,p);
p=strtok(NULL,"");
strcpy(filestr,p);
returntrue;
}
/////////////////////////////////////////////////////////
boolshell(char*str){
intre=-1;
inti;
charcmdstr[SHELL_LEN]="";
charfilestr[FILENAME_LEN]="";
if(strstr(str,"")!
=NULL){
if(!
spile(str,cmdstr,filestr)){printf("输入错误!
");returnfalse;}
}else{
strcpy(cmdstr,str);
}
for(i=0;i!
=shelllen;i++){
if(strcmp(cmdstr,shellstr[i])==0)re=i;
}
switch(re){//根据解释的命令执行对应的操作
case0:
cdexc(filestr);break;
case1:
direxc(filestr);break;
case2:
if(strlen(filestr)==0){errorp(3);returnfalse;}mdexc(filestr);break;
case3:
if(strlen(filestr)==0){errorp(3);returnfalse;}delexc(filestr,cur,true,true);break;
case4:
if(strlen(filestr)==0){errorp(3);returnfalse;}editexc(filestr);break;
case5:
if(strlen(filestr)==0){errorp(3);returnfalse;}delexc(filestr,cur,true,false);break;
case6:
exitexc();break;
default:
errorp(5);break;
}
returntrue;
}
/////////////////////////////////////////////////////////
boolerrorp(intid){
charinput=0;
switch(id){
case0:
puts("路径不存在!
");break;
case1:
{puts("目录非空,是否删除Y/N");input=getchar();getchar();if(input=='Y'||input=='y')returntrue;returnfalse;}
case2:
puts("文件/目录已存在!
");break;
case3:
puts("语法不正确!
");break;
case4:
puts("无法删除根目录!
");break;
case5:
puts("不存在命令!
");break;
case6:
printf("有下列命令可供使用:
\n[1]cd\t切换当前目录\n[2]dir\t显示目录内容\n[3]md\t新建目录\n[4]rd\t删除目录\n[5]edit\t新建文件\n[7]del\t删除文件\n[8]exit\t推出系统\n\n");break;
case7:
puts("删除对象错误!
");break;
default:
puts("未知错误!
");
}
returntrue;
}
/////////////////////////////////////////////////////////
boolboot(){
filenode*p=createnode("root",true,0,NULL);//建立根目录
cur=p;
root=p;
//test();
returntrue;
}
/////////////////////////////////////////////////////////
boolcdexc(char*str){
filenode*fcur=find(str,cur);//find找到路径,并切换
if(strlen(str)==0){returntrue;}
if(strcmp(str,"..")==0){cur=(cur->par!
=NULL?
cur->par:
cur);returntrue;}//特殊父目录符号..
if(fcur==NULL||!
fcur->isdir){errorp(0);returnfalse;}
cur=fcur;
returntrue;
}
/////////////////////////////////////////////////////////
booldirexc(char*str){
char*dirstr[2]={"",""};
filenode*loop=find(str,cur);
if(strlen(str)==0){
loop=cur;
}else{
if(loop==NULL){errorp(0);returnfalse;}elseif(!
loop->isdir){errorp(0);returnfalse;}//判断查找目录是否成功?
}
printf("该目录含有%d个项目\n",loop->i_nlink);
loop=loop->chi;
while(loop!
=NULL){//输出目录所有项目
printf("%s\t%s\n",dirstr[loop->isdir],loop->filename);
loop=loop->nex;
}
returntrue;
}
/////////////////////////////////////////////////////////
boolmdexc(char*str){
filenode*tmp=find(str,cur);
if(strstr(str,"/")!
=NULL){errorp(3);returnfalse;}//判断语法,目录名不能含有“/”
if(tmp!
=NULL){errorp
(2);returnfalse;}//判断目录是否已经存在
tmp=createnode(str,true,0,cur);//创建节点
if(cur->chi!
=NULL){
cur->chi->pre=tmp;//插入该节点
tmp->nex=cur->chi;
}
cur->chi=tmp;
cur->i_nlink++;
returntrue;
}
/////////////////////////////////////////////////////////
booleditexc(char*str){
filenode*tmp=find(str,cur);
intinputc;
if(strstr(str,"/")!
=NULL){errorp(3);returnfalse;}//判断语法,文件名不能含有“/”
if(tmp!
=NULL){errorp
(2);returnfalse;}//判断文件是否已经存在
printf("请输入文件地址:
");scanf("%d",&inputc);getchar();
tmp=createnode(str,false,inputc,cur);//创建节点
if(cur->chi!
=NULL){
cur->chi->pre=tmp;//插入该节点
tmp->nex=cur->chi;
}
cur->chi=tmp;
cur->i_nlink++;
returntrue;
}
/////////////////////////////////////////////////////////
booldelexc(char*str,filenode*fcur,boolmode,booldir){
filenode*loop=NULL;
filenode*looppre=NULL;
filenode*tp=find(str,fcur);
if(strcmp(str,"/")==0){errorp(4);returnfalse;}//删除根目录的处理
loop=cur;
while(loop!
=NULL){if(tp==loop){cur=tp->par;break;}loop=loop->par;}//删除当前目录的上N层目录
if(tp==NULL){if(mode)errorp(0);returnfalse;}//判断是否找到路径,mode为安静模式,不显示警告信息
if(mode)if(tp->isdir!
=dir){errorp(7);returnfalse;}//判断命令要求删除的对象,fileordir
if(tp->isdir){
if(tp->i_nlink!
=0){//判断空目录
if(!
errorp
(1))returnfalse;
loop=tp->chi;
looppre=loop;
while(loop!
=NULL){//递归删除
if(delexc(loop->filename,loop,false,dir)){
loop=looppre->nex;
continue;
}
looppre=loop;
loop=loop->nex;
}
}
}
//删除节点
if(tp->nex!
=NULL)tp->nex->pre=tp->pre;
if(tp->pre!
=NULL){tp->pre->nex=tp->nex;}else{tp->par->chi=tp->nex;}
if(tp->par!
=NULL)tp->par->i_nlink--;
free(tp);
returntrue;
}
/////////////////////////////////////////////////////////
boolexitexc(){
exit(0);
}
/////////////////////////////////////////////////////////
filenode*createnode(char*str,bool_isdir,int_adr,filenode*_par){
filenode*tmp=malloc(sizeof(filenode));
strcpy(tmp->filename,str);
tmp->isdir=_isdir;
tmp->i_nlink=0;
tmp->adr=_adr;
tmp->pre=NULL;
tmp->par=_par;
tmp->chi=NULL;
tmp->nex=NULL;
returntmp;
}
/////////////////////////////////////////////////////////
filenode*find(char*str,filenode*_root){
//x/x/xxx/四种命令情况
filenode*loop=NULL;
charcurstr[FILENAME_LEN]="";//用于存放/左侧字符
char*filestr=strstr(str,"/");//用于存放/右侧字符
if(filestr==NULL){//x相对路径
if(str[0]=='\0'){return_root;}//x/
loop=_root->chi;
while(loop!
=NULL){
if(strcmp(loop->filename,str)==0){
returnloop;
}
loop=loop->nex;
}
returnNULL;
}
if(filestr==str)returnfind(filestr+1,root);///x绝对路径
strncpy(curstr,str,(filestr-str));
loop=_root->chi;
while(loop!
=NULL){//x/x访问目录所有项目进行查找
if(loop->isdir&&strcmp(loop->filename,curstr)==0){
returnfind(filestr+1,loop);//进行递