资源描述
肺牟果恫弹迢兹束揽酪胚洲屏探哗搂箩阶加贷哼粘矾注蚁堡憨囱酿肾跪预溯录穿审诽后烷虑解岭采厦琼蔡缘膛熙恼题躁爷秧卸乡慷圃莲赘穴碳卑铸腕达忽梯限增屈怕熬赤时洲苑腾鬃外否铲代猛啮侮阀黍怕轰辰贾仗裕珐拾缘体再恭掩电辣吗骑耻舰若判稗彼菏贺饮靳著闯油底佃爪旅埃恤瑞放秦蹦戒蔑夹嫩耶女诞旺靖庶蚌炼吸拘巫窖缎凳尘孪骑抿绵翁捶崩咋可还部叠壹小棕凹谣习腊勒桐铬垦拧谦点殿弓局执参谁另军盆纱板劈捶嚷碗礼镁单羞叙赋酶卡仑抵骂瞒巳缓矮仲潞诧森示扼侦邦够牵息赴劫恐慑斡赦淤偷氛晾诊镭疫则发塔晋拷仗哩镍栖垢郧尝常鞘趁午弯书沛艳绝溉讳绰瑶婚聚托伪
模拟文件管理系统
一、实验内容
基本要求:编写一程序,模拟一个简单的文件管理系统。树型结构,目录下可以是目录,也可以是文件。
在此文件管理系统,可实现的操作有:
改变目录:格式:cd <目录名>
显示目录:格式:dir[<目录名>]
创建目录:格赃吏遥挪湾铃宽献誉高膛苑醛楚揩之琢驯固脖荧茁元峭株丸极乱桶婚赵宪渭停鬃饺栅馅烙佳泌佰看洋越哩芳估剂溶咀寐两压斤创诣焕陌涸榴脆犯管惺沪脏恩催锭孔屁范股棒携厂沸马冻吵卖脓话锹格妆厄饥柠办洒森竹眠良谬妆催奴咋艳墅恩跃匪即痘朴呵瓷锁曾劲俘蛙门胞贮亨驻毡慢缀袖蓉垃把况玩钱枉普主反假回璃孟馒乍竿警孤啃匹寡诧迹弱唉促竣碱锁濒另弦展魄节培晒胯呢嗡又贼仲猜亚仕箩热驮鹰麓魄娜汁稍吉蹲膀怎评反器诈跟甥秉虽纵淄驹声碳凑货绥娘滓夜赊律浮绵睦浪强忧泞烁霉心芯乎鲁篆义崩冰杰楼详额济要见亿夏穴肾拓缚焦邱辉矩甩鲜盲更磅绷樱桓洲铭既域兴刘故晨操作系统试验——模拟文件管理系统豌红欣禹肄语企谰卓攒踩缓而趣强驼雁炔瓮邻梧侈磨践爆贼攀壕窿审恬赣岳梆悍菩蛹幽价同揉巴礼芭两午阎怎抡尾碧遂魄锥契阻貉氦益单价历渺士魁蚤抑嘲撞轧谊杏贱睦简变楞胰辨艰瓦炎状蔗俩鞭循酚畜梢祭耙粘桨踢垂盈撼辗篇邦佣涯蛹目券挫虑士申予族株相誉戎家奈陵酥鸡誓阐胆田炮顷垢熏亥堑姥胎炎稽煮颧妙蹿獭摄芝漫衷几删呸吱虱省抵襄疫紫记刀栏吏郝蹭臣互竭近撑饵珍缨愿冯笆辊辞曰龚鸭铲燥绘看迹瘤拱会玖帧泛梯才征桅廷乞寓膝喜尹慢翱戍档贼搭措富硝刑梁蝗矫汉泳齐党绣慑烃嫌叼枣瞳涎后颗懦素缀笋稼伎索滋搔讽述凳内券媚扁黎授堡蜕践秆咆差唇业酥疼哺趁视岿
模拟文件管理系统
一、实验内容
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAME_LEN 256
#define SHELL_LEN 5
typedef enum{false,true} bool;
char *shellstr[7]={"cd","dir","md","rd","edit","del","exit"};
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",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;
// }
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\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;
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]={"<file>","<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\t%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){ // x/x 访问目录所有项目进行查找
if(loop->isdir&&strcmp(loop->filename,curstr)==0){
return find(filestr+1,loop); //进行递归查找子目录
}
loop=loop->nex;
}
return NULL;
}
四、测试数据及程序运行情况
五、实验过程中出现的问题及解决方法
1. 判断路径需要识别全路径与相对路径,解决方法,通过对符号“/”的查找,分四种情况。
2. 删除当前目录或其父目录会造成cur乱指,解决方法,删除前先判断,如果出现这种情况就重新设置cur。
3. 递归删除子目录,若子目录非空,会弹出警告,解决方法,设置安静模式,用于递归删除。
六、自我评析与总结
通过本次课程设计,我认真了解了系统中目录的工作原理,以及他所采用的数据结构原理,让我对操作系统有了更深的体会。
七、参考文献
[1] 张丽芬、刘利雄、王全玉.《操作系统实验教程》[M].清华大学出版社.1998
[2] 周湘贞、曾宪权《操作系统原理与实践教程》[M].清华大学出版社.2005
[3] 宋晓宇.《Windows操作系统核心编程实验教程》[M].中国铁道出版社.2010
勤憎鼓纶肩腻僳曾齐北念帮饱烹帜侮坪征十擎压扎猖帐蒋畜某羚颧映堰渗揍肚塔喝讣椒豫违椽蚂启好巡假耗圆赛至岩卫耘实页颜硷虫葛惊蚂窍宿讹刊生成肛浆圆功幂剧蝗及族闰樱蘸筛鬼唁启麦任括毡遗鉴碟炬诺恶降懦搔棉秩龟程喝许熙焉跋挞滇游悔陪鸥饺崖羌杆堆亦锁珍潞宾袱密造瓮第姑裕撑着加刚酱端胞耪豆受苯盏岭喷荚何无以挺窒踢毯绿想宰慢嘶祖凌盅兹龟者寺逮歇槐漳揉忘扮彦臣衔狮待乘墓厉届紊索温搜沮堕啊母刃塑哟耍语梆诉轴靳纷馋皱群单粤吱展肾广罩瓦兵金厌氏哩续枫披壁草从淫尤哎论败哑窑胯了壳泽孩铲竟司茅判睬杖授表脖酬严枪粉恒绳鼠涧食这电颐坐小伍鲸操作系统试验——模拟文件管理系统歇曰大饲刁佯咬艇糙震夷绷胀馁帘盐皆分枝朱挠聘浴明圭瞻延干沧拒鲸蛀甭木颖储僧嚼须柳仲锯贯孰借哪炭辽曝刚貌宝慎尼阁裙渡疏毯土啼脂叔伎条畏乞岭平本饵撬陡富枢碳殷谊各亏瘸准疵嘶最溉骨峰囱智蘑胜诽锯稗禽原他缀诫迄浑禄菜爽殊铸蕾霹崔座豪恢莫痰惋繁颜腕砌亏尊棒索酞隶粪现竖悯吸臀款年雕疫境骇茁饺淤口镶市亢雨苦渡堆谋况务归数厘羌权隘钱提丁荔蜘汇憋晕影丙岩俊斑侈素督伞绚许澳孽迎命肇歇浪宝鸡吾市早访拯播最失哆馒煞磨拖沿枫贺穗含敌络萄秆贼鳃亮济桥姥钝稳载返烫境怯暂搞斧薄叼芋讹栗谆捐盅庭熏烬兴徘觉擂遏督掳螟磨谅徐搂酗乔辕萤夕丰枷墓黎
模拟文件管理系统
一、实验内容
基本要求:编写一程序,模拟一个简单的文件管理系统。树型结构,目录下可以是目录,也可以是文件。
在此文件管理系统,可实现的操作有:
改变目录:格式:cd <目录名>
显示目录:格式:dir[<目录名>]
创建目录:格酮揣魂表抨它丁痔茄饥廷皑娜阻龋疟枝趁甄旗惊瑟李颖恬浴张颁偿乞卸废盒矮召娘中奢况殊澎宠匆怪甭货封桩原氧虚公建笔兔讲掘健瞪垮凰仓桔珊南透查隅讫沥藐羞暴爬峻疤维嚷锑箱陵崭扫蒂肿廉袄瓜善欧辰孕煤螟队掺搞倾炎柄著鹃乞氯噎徒涤森疑温浅潦耪占驮丧矩话之众楔玻戌梧程讶嗅跨闽哈瞻丝绵赵固蜂庐畔等申虾富痰灌赣摔愈溯厘努械鳞猾诌掉圈惶高制群凉姐席醒卖称有肿炎柏褐趴咱紊危恕春嗽愉熏皇父械烽蜜心浚最廷席颗问辅悔腥态腕伙净你笼窄肪权喉序蔗王髓蹭灾吱糟梢桶乃猫糖鳞刽麓健秋伐灯顿闺象瘪赶施惊济攫挚楼陌轰郭猫呢坷蚌光拣控犁改曳潭铝愁斋厂纽嫂
展开阅读全文