内存文件系统c/c++实现(VS2008)

来源:互联网 发布:魔界战记4 淘宝 编辑:程序博客网 时间:2024/05/16 04:55

刚刚做了这么一个题,用c语言模拟实现文件管理,做完之后对链表、二叉树的操作感觉帮助很大。

要求如下:

  • 系统支持目录与文件。
  • 目录可以包含其它目录与文件。
  • 删除目录时,要求同时删除此目录包含的子目录和文件。
  • 移动目录时,要求同时移动此目录包含的子目录和文件,并保证此目录下的子目录和文件层次结构不发生变化。
  • 根目录为“root”,要求缺省存在。
  • 除根目录(root),目录与文件有且仅有一个父目录。
  • 目录名、文件名分别全局唯一,且大小写敏感。
  • 目录、文件的个数没有限制。
关键代码:
#include <stdio.h>#include<string.h>#include <map>#include <malloc.h>#define NO 0#define OK 1//文件定义struct file{char fileName[300];struct file *nextf;};//目录定义 struct dir{char dirName[300];struct dir* subDir;struct dir* borDir;struct dir* parDir;struct file* fhead;};//全局根目录初始化 struct dir root={"root",NULL,NULL,NULL,NULL}; /*功能描述:根据目录名获得目录指针参数描述:DirName-目录名称 cur-当前目录指针返回值:所查询目录名称的目录指针 */struct dir* getDirByName(const char*DirName,struct dir*cur){if(NULL==cur)return NULL;if(0==strcmp(cur->dirName,DirName)){return cur;}struct dir*res;res=getDirByName( DirName,  cur->borDir);if(NULL==res)res=getDirByName( DirName,cur->subDir);return res;} /*功能描述:根据文件名获得文件指针参数描述:FileName-文件名称 cur-当前目录指针返回值:所查询文件名称的目录指针 */struct file*getFileByName(const char * FileName,struct dir*cur){struct file* p=cur->fhead;while(NULL!=p){if(0==strcmp(p->fileName,FileName)){return p;}p=p->nextf;}p=NULL;if(NULL!=cur->borDir)p=getFileByName(FileName,cur->borDir);if(NULL==p&&NULL!=cur->subDir)p=getFileByName(FileName,cur->subDir);return p;} /*功能描述:判断指定名称目录是否已经存在参数描述:DirName-目录名称 返回值:OK-存在 NO-不存在 */int isDirNameExist(const char * DirName){struct dir* cur=getDirByName(DirName,&root);if(NULL==cur)return NO;return OK;} /*功能描述:判断指定名称文件是否已经存在参数描述:FileName-文件名称 返回值:OK-存在 NO-不存在 */int isFileNameExist(const char * FileName){struct file* cur=getFileByName(FileName,&root);if(NULL==cur)return NO;return OK;} /*功能描述:在指定目录下创建新目录参数描述:ParentDirName-父目录名称  DirName-新目录名称返回值:0-创建成功 -1-创建失败 */int CreateDir(const char * ParentDirName, const char * DirName){//检查父目录、待创建目录名称是否已存在if(NULL==ParentDirName||OK!=isDirNameExist(ParentDirName)||NULL==DirName||OK==isDirNameExist(DirName))return -1;struct dir* parDir=getDirByName(ParentDirName,&root);struct dir* curDir=(struct dir*)malloc(sizeof(struct dir));//如果申请空间失败if(NULL==curDir)return -1;if(NULL==parDir){free(curDir);return -1;}/**********新目录对象赋值开始***********/curDir->fhead=NULL;curDir->subDir=NULL;curDir->borDir=NULL;strcpy(curDir->dirName,DirName);curDir->parDir=parDir;/**********新目录对象赋值结束**********///将新目录插入指定位置if(NULL==parDir->subDir){parDir->subDir=curDir;return 0;}struct dir*p=NULL,*q=NULL;p=parDir->subDir;q=p->borDir;p->borDir=curDir;curDir->borDir=q;return 0;}void CleanSubDir(struct dir*curDir){if(NULL==curDir)return;struct file* fhead=curDir->fhead;struct file* fnext=NULL;while(NULL!=fhead){fnext=fhead->nextf;free(fhead);fhead=fnext;}curDir->fhead=NULL;if(NULL!= curDir->subDir){CleanSubDir(curDir->subDir);free(curDir->subDir);curDir->subDir=NULL;}return;}/*功能描述:删除指定目录参数描述:DirName-目录名称返回值:无*/void DeleteDir(const char * DirName){//检查目录的存在情况、根目录不能删除if(NULL==DirName||OK!=isDirNameExist(DirName)||0==strcmp("root",DirName))return;struct dir* curDir=getDirByName( DirName, &root);struct dir* parDir=curDir->parDir;//情况当前目录下的所有文件及目录CleanSubDir(curDir);if(parDir->subDir==curDir){parDir->subDir=curDir->borDir;free(curDir);return ;}struct dir* p=parDir->subDir;struct dir* q=NULL;while(NULL!=p){q=p;p=p->borDir;if(p==curDir){q->borDir=p->borDir;free(p);break;}}    return;}/*功能描述:判断两个目录是否存在父子目录关系参数描述:parDir-父目录名称  subdir-子目录名称返回值:OK-是父子目录关系 NO-非父子目录关系*/int isTheSubDir(struct dir*parDir,struct dir*subdir){struct dir*p=subdir;while(NULL!=p){if(p->parDir==parDir)return OK;p=p->parDir;}return NO;}/*功能描述:移动目录参数描述:SrcDirName-待移动目录名称  DestDirName-目标移动目录名称返回值:0-移动成功 -1-移动失败*/int MoveDir(const char * SrcDirName, const char * DestDirName){//检查两个目录的存在情况、根节点不移动、两个目录不能相同if(NULL==SrcDirName||NULL==DestDirName||OK!=isDirNameExist(SrcDirName)||OK!=isDirNameExist(DestDirName)||0==strcmp(SrcDirName,DestDirName)||0==strcmp("root",SrcDirName))return -1; struct dir *srcDir=getDirByName(SrcDirName,&root);struct dir *desDir=getDirByName(DestDirName,&root);//目标目录不能使源目录的子目录、源目录不能是目标目录的直接子目录if(OK==isTheSubDir(srcDir,desDir)||srcDir->parDir==desDir)return -1;//将源目录从其父目录剥离if(srcDir->parDir->subDir==srcDir){srcDir->parDir->subDir=srcDir->borDir;}else{struct dir* p,*q;q=srcDir->parDir->subDir;p=q->borDir;while(NULL!=p){if(0==strcmp(p->dirName,SrcDirName)){q->borDir=p->borDir;break;}q=p;p=p->borDir;}}//将源目录移动到目标目录之下srcDir->parDir=desDir;if(NULL==desDir->subDir){desDir->subDir=srcDir;srcDir->borDir=NULL;}else{srcDir->borDir=desDir->subDir;desDir->subDir=srcDir;}    return 0;}/*功能描述:在指定目录下创建文件参数描述:FileName-文件名称,curDir-当前目录返回值:0-创建成功 -1-创建失败*/int CreateFile(const char * DirName, const char * FileName){//检查目录名称、待创建文件名称的存在情况if(NULL==DirName||NULL==FileName||OK!=isDirNameExist(DirName)||OK==isFileNameExist(FileName))return -1;struct dir* curDir=getDirByName( DirName, &root);struct file* newFile=(struct file*)malloc(sizeof(struct file));//判断申请空间是否成功if(NULL==newFile){return -1;}//新文件属性赋值newFile->nextf=NULL;strcpy(newFile->fileName,FileName);//将文件插入指定位置if(NULL==curDir->fhead){curDir->fhead=newFile;}else{newFile->nextf=curDir->fhead;curDir->fhead=newFile;}    return 0;}/*功能描述:删除指定名称的文件-由DeleteFile调用参数描述:FileName-文件名称,curDir-当前目录返回值:NO-未删除 OK-删除成功*/int DeleteFileByName(const char * FileName,struct dir* curDir){if(NULL==curDir)return NO;struct file*p=curDir->fhead;struct file*q=NULL;if(NULL!=p){if(0==strcmp(p->fileName,FileName)){curDir->fhead=p->nextf;free(p);return OK;}else{p=curDir->fhead;q=p->nextf;while(NULL!=q){if(0==strcmp(q->fileName,FileName)){p->nextf=q->nextf;free(q);return OK;}p=q;q=q->nextf;}}}int res=NO;res=DeleteFileByName(FileName,curDir->borDir);if(NO==res)res=DeleteFileByName(FileName, curDir->subDir);return res;}/*功能描述:删除指定名称的文件参数描述:FileName-文件名称返回值:无*/void DeleteFile(const char * FileName){if(NULL==FileName||OK!=isFileNameExist(FileName))return;DeleteFileByName(FileName,&root);    return;}/*功能描述:计算指定目录下的文件数量(包括子目录)参数描述:DirName-目录名称 fileNum-文件数量(输出参数)返回值:无*/void calFileNum(struct dir*curDir,unsigned int *fileNum){if(NULL==curDir)return ;struct file* filep=curDir->fhead;while(NULL!=filep){(*fileNum)++;filep=filep->nextf;}if(NULL!=curDir->borDir)calFileNum(curDir->borDir,fileNum);if(NULL!=curDir->subDir)calFileNum(curDir->subDir,fileNum);}/*功能描述:获取指定目录下的文件数量(包括子目录)参数描述:DirName-目录名称返回值:指定目录下的文件数量*/unsigned int GetFileNum(const char * DirName){unsigned int fileNum=0;if(NULL==DirName||OK!=isDirNameExist(DirName))return fileNum;struct dir*curDir=getDirByName(DirName, &root);if(NULL==curDir)return fileNum;//计算当前目录下的文件数量struct file* filep=curDir->fhead;while(NULL!=filep){fileNum++;filep=filep->nextf;}//计算子目录下文件的数量if(NULL!=curDir->subDir)calFileNum(curDir->subDir,&fileNum);    return fileNum;}/*功能描述:清空文件系统所有信息参数描述:curDir-当前目录返回值:无*/void CleanDir(struct dir*curDir){if(NULL==curDir)return;struct file* fhead=curDir->fhead;struct file* fnext=NULL;while(NULL!=fhead){fnext=fhead->nextf;free(fhead);fhead=fnext;}curDir->fhead=NULL;if(NULL!= curDir->borDir){CleanDir( curDir->borDir);free( curDir->borDir);curDir->borDir=NULL;}if(NULL!= curDir->subDir){CleanDir(curDir->subDir);free(curDir->subDir);curDir->subDir=NULL;}return;}/*功能描述:清空文件系统所有信息,使恢复初始状态参数描述:无返回值:无*/void Clear(void){CleanDir(&root);    return;}

总结
  1. 程序写得还是比较仓促的,还是有很多方面值得改进的,这里我的搜索都是通过递归实现的,想着要是在节点数太多的情况下,性能肯定打折扣。
  2. 增设文件和目录名称的链表,用来单独维护名称的唯一性,搜索时间能提高些,但是想着中间操作会变得复杂,放弃了。


0 0
原创粉丝点击