1、课程设计二:模拟文件管理一设计目的(1) 建立一个简单的模拟文件管理系统。(2) 理解用户界面和操作命令在操作系统中的作用。二设计要求需要实现一个命令行操作界面,包含如下命令:1.创建文件 功能:创立一个指定名字的新文件,即在目录中增加一项,不考虑文件内容,但必须能输入文件长度。2.删除文件 功能:删除指定的文件3.创建目录 功能:在当前路径下创建指定的目录。4.删除目录 功能:删除当前目录下的指定目录,如果该目录为空,则可删除,否则应提示是否作删除,删除操作将该目录下的全部文件和子目录都删除。5.改变目录 功能:工作目录转移到指定的目录下,只要求完成改变到当前目录的某一个子目录下的功能,不要
2、求实现相对目录以及绝对目录。 6.显示目录 功能:显示全部目录以及文件,输出时要求先输出接近根的目录,再输出子目录。对于重名(创建时) ,文件不存在(删除时) ,目录不存在(改变目录时)等错误情况,程序应该作出相应处理并给出错误信息。界面的提示符为#,提示的命令以及调试的方法应和前面的要求一致,可以自己设计更多的命令或者附加功能。三环境本实验是在 windows xp+vc 6.0 环境下实现的,利用 windows SDK 提供的系统接口(API)完成程序功能。在 windows xp 下安装好 VC 后进行,VC 是一个集成开发环境,其中包含了 windows SDK 所有工具,所以就不用
3、单独在安装 SDK 了,程序中所用的 API 是操作系统提供的用来进行应用程序设计的系统功能接口。要使用这些 API,需要包含对这些函数进行说明的 SDK 头文件,最常见的就是 windows.h。一些特殊的 API 调用还需要包含其他的头文件。四步骤1. 打开 VC,选择菜单项 File-New,选择 Project 选项卡并建立一个名为 filesys 的 win32 console application 工程。2. 在工程中创建原文件 filesys.cpp:选择菜单项 Project-Add to Project-File,此时将打开一个新窗口,在其中输入想要创建的文件名字,这里是
4、filesys.cpp,在其中编辑好原文件并保存。3. 通过调用菜单项 Build-Rebuild all 进行编译连接,可以在指定的工程目录下得到debug-filesys.exe 程序,可以在控制台进入该 debug 目录运行程序了。5源代码程序:#include #include #include #include #include #define FILENAME_LEN 21#define INPUT_LEN 81#define COMMAND_LEN 11using namespace std;/结点结构struct FileNode char filenameFILENAME_L
5、EN; /文件名/ 目录名int isdir; /目录文件识别标志int i_nlink; /文件的链接数int adr; /文件的地址struct FileNode *parent, *child;/指向父亲的指针和指向左孩子的指针struct FileNode *sibling_prev, *sibling_next;/指向前一个兄弟的指针和指向/后一个兄弟的指针.;void Init(); /初始化文件树int ParseCommand(); /接受输入的命令并把其分解成操作名和路径文件名void ExecuteCommand(); /执行命令int cdComd(); /处理 cd 命
6、令int creatComd(); /处理 creat 命令int delComd(); /处理 del 命令int dirComd(); /处理 dir 命令int mdComd(); /处理 md 命令int rdComd();int FindPath(char *ph); /寻找参数 ph 所指向的路径int FindFilename(char Para2); /从参数 Para2 中找到要建立或删除的文件、目录名,并把指针只想其父亲结点struct FileNode* CreateFileNode(char filename,int isdir,int i_nlink);/创建结点in
7、t GetInput(char* buffer,unsigned int buffer_len);/获取输入int CheckCommand();/命令检查int GetDir(int begin,char *path,char *curDir);/获取路径void Trim(char *str);struct FileNode *cp, *tp, *root;char pathINPUT_LEN-COMMAND_LEN;/记录当前走过的路径char Para1COMMAND_LEN,Para2INPUT_LEN-COMMAND_LEN;char curpathINPUT_LEN-COMMAN
8、D_LEN,tmppathINPUT_LEN-COMMAND_LEN;char filenameFILENAME_LEN,tmp;unsigned int i,j;/int i,j;/主函数int main()printf(“模拟文件管理系统n“);printf(“ncd 改变目录; creat 创建文件; del 删除文件;n“);printf(“dir 显示目录; md 创建目录; rd 删除目录; exit 退出.n“);printf(“n-n“);Init();/初始化文件树while(1) /printf(“#“);if(ParseCommand()/分解命令ExecuteComma
9、nd();/执行命令return 0;/执行命令子函数void ExecuteCommand()int sign;/根据参数 Para1 调用相应的功能处理模块if(strcmp(Para1,“cd“)=0) sign=cdComd(); /cd 命令else if(strcmp(Para1,“creat“)=0) sign=creatComd();/edit 命令else if(strcmp(Para1,“md“)=0)sign=mdComd();else if(strcmp(Para1,“del“)=0) sign=delComd(); /del 命令else if(strcmp(Para
10、1,“rd“)=0)sign=rdComd();else if(strcmp(Para1,“dir“)=0) sign=dirComd(); /dir 命令else if(strcmp(Para1,“exit“)=0)exit(0); /exit 命令elseprintf(“命令错误,请重试n“); /命令输入不正确,报错/创建结点struct FileNode* CreateFileNode(char filename,int isdir,int i_nlink)/申请结点空间struct FileNode* node=(struct FileNode*)malloc(sizeof(stru
11、ct FileNode);/相应内容赋初值strcpy(node-filename,filename);node-isdir=isdir;node-i_nlink=i_nlink;node-parent=NULL;node-child=NULL;node-sibling_prev=NULL;node-sibling_next=NULL;return node;/初始化文件树void Init()struct FileNode *dir1Node,*dir2Node,*file1Node,*etcNode,*libNode,*userNode,*binNode2,*liuNode,*sunNod
12、e,*ftiNode;strcpy(path,“/“); /根目录写入当前路径/创建文件树的结点dir1Node=CreateFileNode(“dir1“,1,0);dir2Node=CreateFileNode(“dir2“,1,0);file1Node=CreateFileNode(“file1“,0,0);etcNode=CreateFileNode(“etc“,1,0);libNode=CreateFileNode(“lib“,1,0);userNode=CreateFileNode(“user“,1,0);binNode2=CreateFileNode(“bin“,1,0);liu
13、Node=CreateFileNode(“liu“,1,0);sunNode=CreateFileNode(“sun“,1,0);ftiNode=CreateFileNode(“fti“,1,0);cp=tp=root=CreateFileNode(“/“,1,0);/结点相应内容赋值root-parent=NULL;root-child=dir1Node;root-sibling_prev=root-sibling_next=NULL;dir1Node-parent=root;dir1Node-child=NULL;dir1Node-sibling_prev=NULL;dir1Node-si
14、bling_next=dir2Node;dir2Node-parent=NULL;dir2Node-child=libNode;dir2Node-sibling_prev=dir1Node;dir2Node-sibling_next=file1Node;file1Node-parent=NULL;file1Node-child=NULL;file1Node-sibling_prev=dir2Node;file1Node-sibling_next=etcNode;etcNode-parent=NULL;etcNode-child=NULL;etcNode-sibling_prev=file1No
15、de;etcNode-sibling_next=NULL;libNode-parent=dir2Node;libNode-child=liuNode;libNode-sibling_prev=NULL;libNode-sibling_next=userNode;userNode-parent=NULL;userNode-child=NULL;userNode-sibling_prev=libNode;userNode-sibling_next=binNode2;binNode2-parent=NULL;binNode2-child=NULL;binNode2-sibling_prev=user
16、Node;binNode2-sibling_next=NULL;liuNode-parent=libNode;liuNode-child=NULL;liuNode-sibling_prev=NULL;liuNode-sibling_next=sunNode;sunNode-parent=NULL;sunNode-child=NULL;sunNode-sibling_prev=liuNode;sunNode-sibling_next=ftiNode;ftiNode-parent=NULL;ftiNode-child=NULL;ftiNode-sibling_prev=sunNode;ftiNod
17、e-sibling_next=NULL;/获取文件或目录名,并把指针指向其父亲结点int FindFilename(char Para2)i=strlen(Para2)-1;j=0;while(Para2i!=/i-; j+;filenamej=0;/获得逆序的文件或目录名,存入 filename 中if(i0)int sign=FindPath(Para2);if(sign=0) return 0;return 1;/缓冲区安全输入子函数/如果输入超过 buffer_len,则截取前 buffer_len-1 长度的输入,/buffer_len 处字符用/0代替int GetInput(ch
18、ar* buffer,unsigned int buffer_len)unsigned int count=0;/int count=0;while(count“,path);printf(“#“);/获取输入if(GetInput(Inputs,INPUT_LEN)=-1)printf(“输入行太长。n“);return 0;Para10=Para20=0;/获取参数 Para1,即操作名while(Inputsi!= if(cp-parent) cp=cp-parent; /找到父亲结点else return 0; /对当前路径进行相应处理i=strlen(path);while(path
19、i!=/if(i!=0)pathi=0;elsepathi+1=0;else FindPath(Para2);/查找路径printf(“进入工作目录n“);printf(“nn 模拟文件管理系统n“);printf(“ncd 改变目录; creat 创建文件; del 删除文件;n“);printf(“dir 显示目录; md 创建目录; rd 删除目录; exit 退出.n“);printf(“n-n“);return 1;/命令处理子函数void Trim(char *str)int begin,end;char *tmp;begin=0;end=strlen(str);/找到字符串第一个
20、非空格的位置while(strbegin= /去除字符串尾部空格while(str-end= );strend+1=0;/ 除去空格if(beginchild;i+; /滤过/strcpy(path,“/“);else if(cp!=NULLif(cp/指针指向当前目录的左孩子elseprintf(“路径错误!n“);return 0;while(ichild)i+; /略过/if(cp-isdir)cp=cp-child; /继续查找下级目录else printf(“路径错误!n“);return 0;strcat(path,“/“);/ curpath 记录当前要找的路径名while(ph
21、i!=/ if(strcmp(cp-filename,curpath)=0)if(cp-isdir=0)strcpy(path,oldpath);cp=temp;printf(“是文件不是目录.n“);return 0;strcat(path,cp-filename);if(strcmp(cp-filename,curpath)!=0|cp=NULL)strcpy(path,oldpath);cp=temp;printf(“输入路径错误n“);return 0;return 1;/创建文件子函数int creatComd() struct FileNode * temp=CreateFileN
22、ode(“,0,0);int sign;struct FileNode *tp;/路径不能为空if(strlen(Para2)=0)printf(“n 命令格式有错误.n“);return 0;/长度检查if(strlen(Para2)50)printf(“n 文件名过长n“);return 0;/格式检查if (!(isalpha(Para20)|Para20=_|Para20=0|Para20=/)printf(“文件名格式有错!n“);/* 文件首字母可以为字母或数字 或_或/或回车*/return 0;/获取文件名sign=FindFilename(Para2);if(sign=0)r
23、eturn 0;if(cp-isdir!=1)/如当前指针指向的是文件,则报错printf(“you cannot edit a file in under a file!n“);return 0;/创建文件结点,并插入到指定目录下tp=CreateFileNode(“,1,0);strcpy(tp-filename,filename);tp-isdir=0;tp-i_nlink=0;if(cp-child=NULL) tp-parent=cp;tp-child=NULL;cp-child=tp;tp-sibling_prev=NULL;tp-sibling_next=NULL;else te
24、mp=cp;/用 temp 找到新结点插入处temp=temp-child;while(temp-sibling_next )/find the last sibing nodetemp=temp-sibling_next;if(strcmp(temp-filename,filename)=0/重名报错return 0;/找到了最后一个结点temp-sibling_next=tp;tp-parent=NULL;tp-child=NULL;tp-sibling_prev=temp;tp-sibling_next=NULL;printf(“新建文件n“);printf(“nn 模拟文件管理系统n“
25、);printf(“ncd 改变目录; creat 创建文件; del 删除文件;n“);printf(“dir 显示目录; md 创建目录; rd 删除目录; exit 退出.n“);printf(“n-n“);return 1;/删除文件子函数int delComd() int sign;struct FileNode *temp;/参数不能为空if(strlen(Para2)=0)printf(“n 命令格式有错误.n“);return 0;/获取文件名sign=FindFilename(Para2);if(sign=0) return 0;/用 temp 指向要删除的结点if(cp-c
26、hild) temp=cp-child;while(temp-sibling_next if(strcmp(temp-filename,filename)!=0)printf(“不存在该文件!n“);return 0;elseprintf(“不存在该文件!n“);return 0;/要删除的不能是目录if(temp-isdir!=0)printf(“ERROR!该命令只能删除文件,不可删除目录!n“);return 0;/如仍有用户使用该文件,则不能删除if(temp-i_nlink!=0)printf(“还有用户共享了该文件,不能删除!n“);return 0;/删除工作if(temp-pa
27、rent=NULL)/不是第一个孩子temp-sibling_prev-sibling_next=temp-sibling_next;if(temp-sibling_next)/处理是最后一个兄弟的情况temp-sibling_next-sibling_prev=temp-sibling_prev;temp-sibling_prev=temp-sibling_next=NULL;printf(“删除完毕“);/ifelse/第一个孩子 if(temp-sibling_next)/处理是最后一个兄弟的情况temp-sibling_next-parent=temp-parent;temp-pare
28、nt-child= temp-sibling_next;printf(“删除完毕n“);/elsefree(temp);printf(“nn 模拟文件管理系统n“);printf(“ncd 改变目录; creat 创建文件; del 删除文件;n“);printf(“dir 显示目录; md 创建目录; rd 删除目录; exit 退出.n“);printf(“n-n“);return 1;/int mdComd() struct FileNode * temp,*tp;temp=CreateFileNode(“,1,0);int sign;/参数不能为空if(strlen(Para2)=0)
29、printf(“n 命令格式有错误.n“);return 0;/长度检查if(strlen(Para2)50)printf(“n 目录名过长n“);return 0;/格式检查if (!(isalpha(Para20)|Para20=_|Para20=0|Para20=/)printf(“目录名格式有错!n“);/* 目录首字母可以为字母或数字 或/*/return 0;/获取目录名sign=FindFilename(Para2);if(sign=0)return 0;if(cp-isdir!=1)/如当前指针指向的是文件,则报错printf(“you cannot edit a direct
30、ory in under a file!n“);return 0;/创建目录结点,并插入到指定目录下tp=CreateFileNode(filename,1,0);if(cp-child=NULL) tp-parent=cp;tp-child=NULL;cp-child=tp;tp-sibling_prev=NULL;tp-sibling_next=NULL;else temp=cp;/用 temp 找到新结点插入处temp=temp-child;while(temp-sibling_next )/find the last sibing nodetemp=temp-sibling_next;
31、if(strcmp(temp-filename,filename)=0/重名报错return 0;/找到了最后一个结点temp-sibling_next=tp;tp-parent=NULL;tp-child=NULL;tp-sibling_prev=temp;tp-sibling_next=NULL;printf(“创建目录n“);printf(“nn 模拟文件管理系统n“);printf(“ncd 改变目录; creat 创建文件; del 删除文件;n“);printf(“dir 显示目录; md 创建目录; rd 删除目录; exit 退出.n“);printf(“n-n“);retur
32、n 1;int rdComd() int sign;struct FileNode *temp;char cmd2;/命令检查if(!CheckCommand()return 0;/获取目录名sign=FindFilename(Para2);if(sign=0) return 0;/用 temp 指向要删除的结点if(cp-child) temp=cp-child;while(temp-sibling_next if(strcmp(temp-filename,filename)!=0)printf(“不存在该目录!n“);return 0;elseprintf(“不存在该目录!n“);retu
33、rn 0;/要删除的不能是文件if(temp-isdir!=1)printf(“ERROR!该命令只能删除目录,不可删除文件!n“);return 0;/如仍有用户使用该目录,则不能删除if(temp-child)printf(“n 该目录不为空,您确定要删除吗?Y/N!n“);GetInput(cmd,2);if(strcmp(cmd,“n“)=0|strcmp(cmd,“N“)=0)return 0;/删除工作if(temp-parent=NULL)/不是第一个孩子temp-sibling_prev-sibling_next=temp-sibling_next;if(temp-siblin
34、g_next)/处理是最后一个兄弟的情况temp-sibling_next-sibling_prev=temp-sibling_prev;temp-sibling_prev=temp-sibling_next=NULL;/ifelse/第一个孩子 if(temp-sibling_next)/处理是最后一个兄弟的情况temp-sibling_next-parent=temp-parent;temp-parent-child= temp-sibling_next;/elseprintf(“删除目录n“);printf(“nn 模拟文件管理系统n“);printf(“ncd 改变目录; creat
35、创建文件; del 删除文件;n“);printf(“dir 显示目录; md 创建目录; rd 删除目录; exit 退出.n“);printf(“n-n“);free(temp);return 1;/显示目录子函数int dirComd()if(strlen(Para2)0)int sign=FindPath(Para2);/查找路径if(sign=0)return 0;elseprintf(“n%s“, path);if(cp!=root)printf(“ %sn“,“);if(cp-child=NULL) return 0;/指定目录为空tp=cp;/指定目录不为空,显示其所有子目录及
36、文件名tp=tp-child;while(tp)if(tp-isdir)printf(“ %sn“,tp-filename);elseprintf(“ %sn“,tp-filename);tp=tp-sibling_next;printf(“显示目录n“);printf(“nn 模拟文件管理系统n“);printf(“ncd 改变目录; creat 创建文件; del 删除文件;n“);printf(“dir 显示目录; md 创建目录; rd 删除目录; exit 退出.n“);printf(“n-n“);return 0;/后加的int CheckCommand()if(strlen(Para2)=0)printf(“命令语法不正确.n“);return 0;return 1;六运行结果分析1.在控制台窗口的提示符下输入 filesys 回车2.创建文件3.删除文件4.创建目录.5.删除目录6.改变目录7.显示目录