您好,欢迎来到图艺博知识网。
搜索
您的当前位置:首页操作系统试验——模拟文件管理系统【用心整理精品资料】

操作系统试验——模拟文件管理系统【用心整理精品资料】

来源:图艺博知识网
模拟文件管理系统

一、实验内容

1. 基本要求:编写一程序,模拟一个简单的文件管理系统。树型结构,目录

下可以是目录,也可以是文件。

在此文件管理系统,可实现的操作有: 改变目录:格式:cd 〈目录名〉 显示目录:格式:dir[〈目录名>] 创建目录:格式:md 〈目录名〉 删除目录:格式:rd<目录名> 新建文件:格式:edit〈文件名〉 删除文件:格式:del〈文件名〉 退出文件系统:exit

2. 目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开 3. 功能具体描述:

改变目录:改变当前工作目录,目录不存在是给出出错信息

显示目录:显示指定目录下或当前目录下所有文件和一级目录(选做:带/s参数的dir命令,显示所有子目录)

创建目录:在指定路径或当前路径下创建指定目录。重名时给出出错信息。 删除目录:删除指定目录下所有文件和子目录。要删目录不空时,要给出提示是否要删除.

创建文件:创建指定名字的文件,只要创建表示文件的节点即可,内容及大小不考虑。

删除文件:删除指定文件,不存在时给出出错信息。 退出文件系统:exit 4. 总体流程: 初始化文件目录

输出提示符,等待接受命令,分析键入的命令;

对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令。直到键入exit退出为止。

二、数据结构设计

Struct FileNode {

Char filename[FILENAME_LEN];//文件名/目录名 Int isdir ;//目录、文件的识别标志 Int i_nlink;//文件链接数 Int adr;//文件的地址

Struct FileNode *parent,*child;//指向父亲的指针和左孩子的指针 Struct FileNode *sibling_prev,*sibling_next;//指向前一个兄弟的指针和后一个兄弟的指针。

}

三、算法设计 3.1 功能模块图

3.2 算法思路

3.2.1实现方法

bool spile(char *str,char *cmdstr,char *filestr);//切割字符串 bool shell(char *str); //用来解释命令 bool errorp(int id); //打印错误提示 bool boot(); //启动初始化

filenode* find(char *str,filenode *_root); //递归对目录树进行查找 bool cdexc(char *str); //执行cd命令 bool direxc(char *str); //执行dir命令 bool mdexc(char *str); //执行md命令 bool editexc(char *str); //执行edit命令

bool delexc(char *str,filenode *fcur,bool mode,bool dir); //执行del命令

bool exitexc(); //退出

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\"};//命令字符串 int shelllen=7;

//命令的字符串的长度

(2)主函数模块

调用boot模块初始化,然后使用while循环,每次循环中用户可以输入命令字符串,调用shell模块进行解释并执行操作,执行完成后再次进入循环,直到用户使用exit退出。

(3)其他模块说明(用文字描述,不要代码)

删除模块:调用find函数查找到目录节点,然后进行删除节点操作,并注

意特殊情况。

新建目录/文件模块:通过调用find查找是否重复,若不重复就进行增加节点。

切换目录模块:通过find函数找到节点,然后将cur指针指向该节点. 显示目录模块:通过find函数找到节点,循环遍历该节点显示。 退出模块:执行exit函数。

代码:

#include #include 〈stdlib.h> #include #define FILENAME_LEN 256 #define SHELL_LEN 5

typedef enum{false,true} bool;

char *shellstr[7]={\"cd\",\"dir”,\"md\",”rd”,”edit”,\"del\}; int shelllen=7; //命令的字符串的长度

typedef struct filenode_i{ //文件节点 char filename[FILENAME_LEN]; //文件名 bool isdir; //是否目录 int i_nlink; //文件连接数 int adr; //文件地址 struct filenode_i *par; //指向父节点 struct filenode_i *chi; //指向第一个孩子节点 struct filenode_i *pre; //指向上一个兄弟节点 struct filenode_i *nex; //指向下一个兄弟节点 }filenode;

filenode *cur=NULL; //指向当前目录 filenode *root=NULL; //指向根节点目录

bool spile(char *str,char *cmdstr,char *filestr);//切割字符串 bool shell(char *str); //用来解释命令 bool errorp(int id); //打印错误提示 bool boot(); //启动初始化

filenode* find(char *str,filenode *_root); //递归对目录树进行查找

bool cdexc(char *str); //执行cd命令 bool direxc(char *str); //执行dir命令 bool mdexc(char *str); //执行md命令 bool editexc(char *str); //执行edit命令

bool delexc(char *str,filenode *fcur,bool mode,bool dir); //执行del命令 bool exitexc(); //退出

filenode* createnode(char *str,bool _isdir,int _adr,filenode *_par);

main(){

char inputs[FILENAME_LEN]=\"”; boot(); errorp(6); while(1){ printf(”\\n〉\"); gets(inputs); shell(inputs); } }

//下面进行函数的实现

//////////////////////////////////////////////////////////////////

//**************************************************************

////test

// test(){ //这是用来对目录进行测试,在一开始建立目录结构

// filenode *p=createnode(\"hello\,0,root); // filenode *p2=NULL; // root—>i_nlink=2;

// root-〉chi=p;p->par=root;

// p2=createnode(”hello2\,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; // }

bool spile(char *str,char *cmdstr,char *filestr){ char strclo[FILENAME_LEN]=\"\"; char *p=NULL; strcpy(strclo,str); p=strtok(strclo,” ”); //调用的strok进行分割 if(p==NULL) return false; strcpy(cmdstr,p); p=strtok(NULL,” \"); strcpy(filestr,p); return true; }

/////////////////////////////////////////////////////////

bool shell(char *str){ int re=-1; int i; char cmdstr[SHELL_LEN]=””; char filestr[FILENAME_LEN]=\"”; if(strstr(str,\" \")!=NULL){ if(!spile(str,cmdstr,filestr)) {printf(”输入错误!”);return false;} }else{ strcpy(cmdstr,str); } for(i=0;i!=shelllen;i++){ if(strcmp(cmdstr,shellstr[i])==0) re=i; } switch(re){ //根据解释的命令执行对应的操作 case 0: cdexc(filestr);break; case 1: direxc(filestr);break; case 2: if(strlen(filestr)==0) {errorp(3);return false;}mdexc(filestr);break; case 3: if(strlen(filestr)==0) {errorp(3);return false;}delexc(filestr,cur,true,true);break; case 4: if(strlen(filestr)==0) {errorp(3);return false;}editexc(filestr);break; case 5: if(strlen(filestr)==0) {errorp(3);return false;}delexc(filestr,cur,true,false);break; case 6: exitexc();break; default:errorp(5);break; } return true; }

///////////////////////////////////////////////////////// bool errorp(int id){ char input=0; switch(id){ case 0 : puts(”路径不存在!”);break; case 1 : {puts(”目录非空,是否删除Y/N”);input=getchar();getchar();if(input=='Y'||input==’y')return true;return false;} case 2 : puts(\"文件/目录已存在!\");break; case 3 : puts(”语法不正确!\");break; case 4 : puts(”无法删除根目录!”);break; case 5 : puts(\"不存在命令!\");break; case 6 : printf(”有下列命令可供使用:\\n[1] cd\切换当前目录\\n[2] dir\显示目录内容\\n[3] md\新建目录\\n[4] rd\删除目录\\n[5] edit\新建文件\\n[7] del\删除文件\\n[8] exit\推出系统\\n\\n”);break; case 7 : puts(”删除对象错误!\");break; default: puts(”未知错误!”);

} return true; }

///////////////////////////////////////////////////////// bool boot(){ filenode *p=createnode(”root”,true,0,NULL); //建立根目录 cur=p; root=p; //test(); return true; }

///////////////////////////////////////////////////////// bool cdexc(char *str){

filenode *fcur=find(str,cur); //find找到路径,并切换 if(strlen(str)==0) {return true;} if(strcmp(str,”.。\")==0){cur=(cur—〉par!=NULL?cur—>par:cur);return true;}//特殊父目录符号 .。

if(fcur==NULL||!fcur—>isdir) {errorp(0);return false;} cur=fcur; return true; }

///////////////////////////////////////////////////////// bool direxc(char *str){

char *dirstr[2]={\"\〈dir>\"}; filenode *loop=find(str,cur); if(strlen(str)==0){ loop=cur; }else{

if(loop==NULL){errorp(0);return false;} else if(!loop—〉isdir){errorp(0);return false;} //判断查找目录是否成功? }

printf(”该目录含有%d个项目\\n”,loop-〉i_nlink); loop=loop->chi;

while(loop!=NULL){ //输出目录所有项目 printf(”%s\%s\\n”,dirstr[loop—>isdir],loop—>filename); loop=loop—〉nex; }

return true; }

///////////////////////////////////////////////////////// bool mdexc(char *str){ filenode *tmp=find(str,cur); if(strstr(str,\"/\")!=NULL) {errorp(3);return false;} //判断语法,目录名不能含

有“/” if(tmp!=NULL) {errorp(2);return false;} //判断目录是否已经存在 tmp=createnode(str,true,0,cur); //创建节点 if(cur—〉chi!=NULL) { cur—〉chi—>pre=tmp; //插入该节点 tmp->nex=cur—>chi; } cur—>chi=tmp; cur-〉i_nlink++; return true; }

///////////////////////////////////////////////////////// bool editexc(char *str){ filenode *tmp=find(str,cur); int inputc; if(strstr(str,”/\")!=NULL) {errorp(3);return false;} //判断语法,文件名不能含有“/” if(tmp!=NULL) {errorp(2);return false;} //判断文件是否已经存在 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++; return true; }

/////////////////////////////////////////////////////////

bool delexc(char *str,filenode *fcur,bool mode,bool dir){ filenode *loop=NULL; filenode *looppre=NULL; filenode *tp=find(str,fcur); if(strcmp(str,\"/”)==0) {errorp(4);return false;} //删除根目录的处理 loop=cur; while(loop!=NULL){if(tp==loop) {cur=tp->par;break;}loop=loop—〉par;} //删除当前目录的上N层目录 if(tp==NULL){if(mode) errorp(0);return false;} //判断是否找到路径,mode为安静模式,不显示警告信息 if(mode) if(tp-〉isdir!=dir) {errorp(7);return false;} //判断命令要求删除的对象,file or dir

if(tp—>isdir){ if(tp—〉i_nlink!=0){ //判断空目录 if(!errorp(1)) return false; 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); return true; }

///////////////////////////////////////////////////////// bool exitexc(){ 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; return tmp; }

///////////////////////////////////////////////////////// filenode* find(char *str,filenode *_root){ // x/x /x x x/ 四种命令情况 filenode *loop=NULL; char curstr[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){ return loop; } loop=loop-〉nex; } return NULL; }

if(filestr==str) return find(filestr+1,root); // /x

strncpy(curstr,str,(filestr-str)); loop=_root—〉chi; while(loop!=NULL){ 录所有项目进行查找 if(loop->isdir&&strcmp(loop—〉filename,curstr)==0){ return find(filestr+1,loop); 子目录 } loop=loop->nex; }

return NULL; }

绝对路径 // x/x 访问目 //进行递归查找

四、测试数据及程序运行情况

五、实验过程中出现的问题及解决方法

1. 判断路径需要识别全路径与相对路径,解决方法,通过对符号“/”的查

找,分四种情况。

2. 删除当前目录或其父目录会造成cur乱指,解决方法,删除前先判断,如

果出现这种情况就重新设置cur。

3. 递归删除子目录,若子目录非空,会弹出警告,解决方法,设置安静模式,

用于递归删除.

六、自我评析与总结

通过本次课程设计,我认真了解了系统中目录的工作原理,以及他所采用的数据结构原理,让我对操作系统有了更深的体会。

七、参考文献

[1] 张丽芬、刘利雄、王全玉.《操作系统实验教程》[M].清华大学出版社。1998 [2] 周湘贞、曾宪权《操作系统原理与实践教程》[M].清华大学出版社。2005 [3] 宋晓宇。《Windows操作系统核心编程实验教程》[M].中国铁道出版社.2010

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuoyibo.net 版权所有 湘ICP备2023021910号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务