文件管理系统C++.docx
《文件管理系统C++.docx》由会员分享,可在线阅读,更多相关《文件管理系统C++.docx(34页珍藏版)》请在冰豆网上搜索。
文件管理系统C++
一.课程设计目的及要求
深入了解文件管理系统,初步掌握文件管理系统的实现法。
用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。
从而对各种文件操作命令的实质容和执行过程有比拟深入的了解。
编写一程序,模拟一个简单的文件管理系统。
树型构造,目录下可以是目录,也可以是文件。
在此文件管理系统,可实现的操作有:
改变目录:
格式:
cd<目录名>
显示目录:
格式:
dir<目录名>
创立目录:
格式:
md<目录名>
删除目录:
格式:
rd<目录名>
新建文件:
格式:
edit<文件名>
删除文件:
格式:
del<文件名>
退出文件系统:
exit
二.相关知识
1.文件构造体
structFileNode
{
charfilename[FILENAME_LEN];//文件名/目录名
intisdir;//目录文件识别标志
inti_nlink;//文件的数
intadr;//文件的地址
structFileNode*parent,*child;//指向父亲的指针和指向左孩子的指针
structFileNode*sibling_prev,*sibling_next;//指向前一个兄弟的指针和指向
//后一个兄弟的指针.
};
整个文件系统采用二叉树型存储构造,初始化文件树如下:
图2-1初始目录树
2.所使用函数及其功能
intMain();//主函数
voidInit();//初始化文件树
intParsemand();//承受输入的命令并把其分解成操作名和路径文件名
voidExecutemand();//执行命令,分别执行cd,edit,md,del,rd,dir,exit命令
intcdd();//改变目录功能处理
inteditd();//处理edit命令,即创立文件,只要创立表示文件的节点即可,容及大小不考虑
intmdd();//创立目录
intdeld();//处理del命令,即删除指定文件,不存在是给出错误信息
intdird();//处理dir命令,显示目录
intrdd();//删除目录
intFindFilename(charPara2[]);//查找文件名
structFileNode*CreateFileNode(charfilename[],intisdir,inti_nlink);//创立结点
intGetInput(char*buffer,unsignedintbuffer_len);//获取输入
3.所使用的变量
structFileNode*cp,*tp,*root;//*cp,*tp,*root是根目录节点
charpath[INPUT_LEN-MAND_LEN];//记录当前走过的路径
charPara1[MAND_LEN],Para2[INPUT_LEN-MAND_LEN];//para1数组存储输入的命令,para2数组存储输入的文件名
charfilename[FILENAME_LEN],tmp;
unsignedinti,j;
三题目分析
1.文件系统采用二叉树型存储构造,结点构造如下:
structFileNode
{
charfilename[FILENAME_LEN];//文件名/目录名
intisdir;//目录、文件的识别标志〔0为文件,1为目录〕
inti_nlink;//文件的数
//intadr;//文件的地址
structFileNode*parent,*child;//指向父亲的指针和指向左孩子的指针
structFileNode*sibling_prev,*sibling_next;//指向前一个兄弟的指针和指向后一个兄弟的指针.
};
2.目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/〞隔开
3.功能具体描述:
改变目录:
改变当前工作目录,目录不存在时给出出错信息
显示目录:
显示指定目录下或当前目录下所有文件和一级目录〔选做:
带/s参数的dir命令,显示所有子目录〕
创立目录:
在指定路径或当前路径下创立指定目录。
重名时给出错信息。
删除目录:
删除指定目录下所有文件和子目录。
要删目录不空时,要给出提示是否要删除。
创立文件:
创立指定名字的文件,只要创立表示文件的节点即可,容及大小不考虑。
删除文件:
删除指定文件,不存在时给出出错信息。
退出文件系统:
exit
4、总体流程:
初始化文件目录;
输出提示符,等待承受命令,分析键入的命令;
对合法的命令,执行相应的处理程序,否那么输出错误信息,继续等待新命令,直到键入EXIT退出为止。
四.概要设计
1.在存中开辟一个虚拟磁盘空间作为文件存储器,在其上实现一个简单的单用户文件系统。
2.文件存储空间的分配采用显式分配。
为了实现创立和删除文件必须要有一棵初始的文件树存在,以便在文件树的根节点下实现创立和删除文件。
3.数据构造与树构造。
数据构造是计算机存储、组织数据的式。
数据构造是指相互之间存在一种或多种特定关系的数据元素的集合。
树是一种重要的非线性数据构造,直观地看,它是数据元素〔在树中称为结点〕按分支关系组织起来的构造,很象自然界中的树那样。
树中每个分叉点称为结点,起始结点称为树根,任意两个结点间的连接关系称为树枝,结点下面不再有分枝称为树叶。
结点的前趋结点称为该结点的"双亲",结点的后趋结点称为该结点的"孩子",同一结点的"孩子"之间互称"兄弟"。
4.文件目录构造采用多级目录构造。
为了简单起见,可以使用文件构造体,构造体容包括:
文件名,文件目录识别标示,文件数,以及他的左孩子右孩子左兄弟右兄弟指
5.要有分解函数对输入的命令进展分解。
以识别那局部是哪局部是命令,哪局部是路径和文件名。
6.最后要有执行函数。
来执行输入的创立文件命令。
五.代码及流程
图5-1主函数流程图
2〕edit()创立文件函数流程图
图5-2创立文件函数流程图
图5-3删除函数流程图
4〕Parsemand()分解命令函数流程图
图5-4分解命令函数流程图
5〕改变目录函数rdd()
图5-5改变目录函数流程图
源代码:
#include
#include
#include
#include
#include
#defineFILENAME_LEN21
#defineINPUT_LEN81
#defineMAND_LEN11
usingnamespacestd;
voidInit();//初始化文件树
intParsemand();//承受输入的命令并把其分解成操作名和路径文件名
voidExecutemand();//执行命令
intcdd();//处理cd命令
inteditd();//处理edit命令
intdeld();//处理del命令
intdird();//处理dir命令
intmdd();//处理md命令
intrdd();//处理rd命令
intFindPath(char*ph);//寻找参数ph所指向的路径
intFindFilename(charPara2[]);//从参数Para2中找到要建立或删除的文件、目录名,并把指针只想其父亲结点
structFileNode*CreateFileNode(charfilename[],intisdir,inti_nlink);//创立结点
intGetInput(char*buffer,unsignedintbuffer_len);//获取输入
intCheckmand();//命令检查
intGetDir(intbegin,char*path,char*curDir);//获取路径
structFileNode*cp,*tp,*root;
charpath[INPUT_LEN-MAND_LEN];//记录当前走过的路径
charPara1[MAND_LEN],Para2[INPUT_LEN-MAND_LEN];
charcurpath[INPUT_LEN-MAND_LEN],tmppath[INPUT_LEN-MAND_LEN];
charfilename[FILENAME_LEN],tmp;
unsignedinti,j;//inti,j;
structFileNode//结点构造
{
charfilename[FILENAME_LEN];//文件名/目录名
intisdir;//目录文件识别标志
inti_nlink;//文件的数
structFileNode*parent,*child;//指向父亲的指针和指向左孩子的指针
structFileNode*sibling_prev,*sibling_next;//指向前一个兄弟的指针和指向后一个兄弟的指针.
};
//创立结点
structFileNode*CreateFileNode(charfilename[],intisdir,inti_nlink){
structFileNode*node=(structFileNode*)malloc(sizeof(structFileNode));//申请结点空间
//相应容赋初值
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;
returnnode;
}
//初始化文件树
voidInit(){
structFileNode*binNode,*usrNode,
*unixNode,*etode,*libNode,*userNode,
*binNode2,*liuNode,*sunNode,*ftiNode;
strcpy(path,"/");//根目录写入当前路径
//创立文件树的结点
binNode=CreateFileNode("bin",1,0);
usrNode=CreateFileNode("usr",1,0);
unixNode=CreateFileNode("unix",0,0);
etode=CreateFileNode("etc",1,0);
libNode=CreateFileNode("lib",1,0);
userNode=CreateFileNode("user",1,0);
binNode2=CreateFileNode("bin",1,0);
liuNode=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=binNode;
root->sibling_prev=root->sibling_next=NULL;
binNode->parent=root;
binNode->child=NULL;
binNode->sibling_prev=NULL;
binNode->sibling_next=usrNode;
usrNode->parent=NULL;
usrNode->child=libNode;
usrNode->sibling_prev=binNode;
usrNode->sibling_next=unixNode;
unixNode->parent=NULL;
unixNode->child=NULL;
unixNode->sibling_prev=usrNode;
unixNode->sibling_next=etode;
etode->parent=NULL;
etode->child=NULL;
etode->sibling_prev=unixNode;
etode->sibling_next=NULL;
libNode->parent=usrNode;
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=userNode;
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;
ftiNode->sibling_next=NULL;
}
//获取文件或目录名,并把指针指向其父亲结点
intFindFilename(charPara2[]){
i=strlen(Para2)-1;
j=0;
while(Para2[i]!
='/'&&i>=0){
filename[j]=Para2[i];
i--;j++;
}
filename[j]='\0';//获得逆序的文件或目录名,存入filename中
if(i<0)Para2[i+1]='\0';
elsePara2[i]='\0';
j--;
for(i=0;itmp=filename[i];
filename[i]=filename[j];
filename[j]=tmp;
}
if(strlen(Para2)>0){//查找路径
intsign=FindPath(Para2);
if(sign==0)
return0;
}
return1;
}
//缓冲区平安输入子函数
//如果输入超过buffer_len,那么截取前buffer_len-1长度的输入,
//buffer_len处字符用'/0'代替
intGetInput(char*buffer,unsignedintbuffer_len){
unsignedintcount=0;
while(countif((buffer[count]=getchar())==10){
buffer[count]='\0';
returncount;
}
count++;
}
while(getchar()!
=10);
buffer[buffer_len-1]='\0';
return-1;
}
//改变目录函数
intcdd(){
if(!
Checkmand())//命令检查
return0;
if(strcmp(Para2,"..")==0){//对cd..命令的处理
inti;
while(cp->sibling_prev)
cp=cp->sibling_prev;
if(cp->parent)
{cp=cp->parent;}//找到父亲结点
else
{return0;}
//对当前路径进展相应处理
i=strlen(path);
while(path[i]!
='/'&&i>0)i--;
if(i!
=0)
path[i]='\0';
else
path[i+1]='\0';
}
else{
FindPath(Para2);//查找路径
}
return1;
}
//创立目录函数
intmdd(){
structFileNode*temp,*tp;
temp=CreateFileNode("",1,0);
intsign;
if(strlen(Para2)==0){//参数不能为空
printf("\n命令格式有错误.\n");
return0;
}
if(strlen(Para2)>20){//长度检查
printf("\n目录名过长\n");
return0;
}
//格式检查
if(!
(isalpha(Para2[0])||Para2[0]=='_'||Para2[0]=='\0'||Para2[0]=='/')){
printf("目录名格式有错!
\n");/*目录首字母可以为'字母'或'数字'或'/'*/
return0;
}
sign=FindFilename(Para2);//获取目录名
if(sign==0)
return0;
if(cp->isdir!
=1){//如当前指针指向的是文件,那么报错
printf("youcannoteditadirectoryinunderafile!
\n");
return0;
}
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){//findthelastsibingnode
temp=temp->sibling_next;
if(strcmp(temp->filename,filename)==0&&temp->isdir==1){
printf("此目录名已存在\n");//重名报错
return0;
}
}//找到了最后一个结点
temp->sibling_next=tp;
tp->parent=NULL;
tp->child=NULL;
tp->sibling_prev=temp;
tp->sibling_next=NULL;
}
return1;
}
//删除目录函数
intrdd(){
intsign;
structFileNode*temp;
charcmd[2];
if(!
Checkmand())//命令检查
return0;
sign=FindFilename(Para2);//获取目录名
if(sign==0)return0;
if(cp->child){//用temp指向要删除的结点
temp=cp->child;
while(temp->sibling_next&&(strcmp(temp->filename,filename)!
=0||temp->isdir!
=1))
temp=temp->sibling_next;
if(strcmp(temp->filename,filename)!
=0){
printf("不存在该目录!
\n");
return0;
}
}
else{
printf("不存在该目录!
\n");
return0;
}
if(temp->isdir!
=1){//要删除的不能是文件
printf("ERROR!
该命令只能删除目录,不可删除文件!
\n");
return0;
}
if(temp->child){//如仍有用户使用该目录,那么不能删除
printf("\n该目录不为空,您确定要删除吗?
Y/N!
\n");
GetInput(cmd,2);
if(strcmp(cmd,"n")==0||strcmp(cmd,"N")==0)
return0;
}
//删除工作
if(temp->parent==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;
}//if
else{//第一个孩子
if(temp->sibling_next)//处理是最后一个兄弟的情况
temp->sibling_next->parent=temp->parent;
temp->parent->child=temp->sibling_next;
}
free(temp);
return1;
}
//显示目录子函数
intdird(){
if(strlen(Para2)>0){
intsign=FindPath(Para2);//查找路径
if(sign==0){return0;}
else
{printf("\n%s>",path);}
}
if(cp!
=root)
printf("
%s\n","