<每日 1 OJ> -内存文件系统
蛮有意思的,主要考查链表和树结构的知识。
代码如下:
******************************************************************************/
#include "FileManager.h"
//#include <stdafx.h>
#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;//p310 链表 *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;
curDir->parDir=parDir;
strcpy(curDir->dirName,DirName);
/**********新目录对象赋值开始***************/ //将新目录插入指定位置
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); //如果父目录下头指针指向这个目录,那么将这个头指针赋给它的兄弟目录,将这个指针free掉
if(parDir->subDir==curDir)
{
parDir->subDir=curDir->borDir;
free(curDir);
return; }
//如果父目录头指针不是指向这个目录,那么遍历父目录指针的子目录,找到这个目录的指针,将这个指针解放掉。将其释放掉。即a->b->c 删除b ,那么a->c
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; /********************将源目录从其父目录剥离********************/
//如果src 的父目录的子目录头指针指向src ,那么将src的父目录的子目录的头指针指向src 的兄弟目录
if(srcDir->parDir->subDir==srcDir)
{
srcDir->parDir->subDir=srcDir->borDir;
}
//如果src 的父目录的子目录头指针不是指向src ,那么遍历src的父目录的子目录,找出src,然后将src的指针删除掉 a->b->c a->c 将b(src)删除
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 OJ> -内存文件系统的更多相关文章
- Spark入门实战系列--10.分布式内存文件系统Tachyon介绍及安装部署
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Tachyon介绍 1.1 Tachyon简介 随着实时计算的需求日益增多,分布式内存计算 ...
- [CareerCup] 8.9 An In-memory File System 内存文件系统
8.9 Explain the data structures and algorithms that you would use to design an in-memory file system ...
- linux内存文件系统之指南
内存文件系统使用及示例:ramdisk, ramfs, tmpfs 第一部分在Linux中可以将一部分内存mount为分区来使用,通常称之为RamDisk. RamDisk有三种实现方式: 第一种就是 ...
- 文件存储之-内存文件系统tmpfs
前言 我们都知道,对于单台服务器来说,除了 CPU ,内存就是我们存储数据最快的设备.如果可以把数据直接存储在内存中,对于性能的提升就不言而喻了.那么我们先来讲讲如何使用内存来存储文件. 首先,我们先 ...
- [LeetCode] Design In-Memory File System 设计内存文件系统
Design an in-memory file system to simulate the following functions: ls: Given a path in string form ...
- Linux 内存文件系统
Linux内存文件系统:可满足高IO的要求 ramdisk: 基于虚拟在内存中的其他文件系统(ex2fs). 挂载方式:mount /dev/ram /mnt/ramdisk ramfs: 物理内存文 ...
- linux的内存文件系统tmpfs
在centos系统上自带的内存文件系统.这个tmpfs是temporary file system的意思. 一. 使用命令 df -h 查看tmpfs是否正在运行. Filesystem Size U ...
- Tachyon:Spark生态系统中的分布式内存文件系统
转自: http://www.csdn.net/article/2015-06-25/2825056 摘要:Tachyon把内存存储的功能从Spark中分离出来, 使Spark可以更专注计算的本身, ...
- Linux 内存文件系统-ramfs and tmpfs
Linux内存文件系统:可满足高IO的要求 ramdisk: 基于虚拟在内存中的其他文件系统(ex2fs). 挂载方式:mount /dev/ram /mnt/ramdisk ramfs: 物理内存文 ...
随机推荐
- 2019 找钢网java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.找钢网等公司offer,岗位是Java后端开发,因为发展原因最终选择去了找钢网,入职一年时间了,也成为了面试官 ...
- vue跳转链接(新页签)
const {href} = this.$router.resolve({path:"/hosScreen"}); window.open(href, '_blank');
- webpack面试题
1.webpack的核心概念 Entry:入口,Webpack进行打包的起始点(文件) Output:出口,webpack编译打包生成的bundle(打包文件) Loader:模块加载(转换)器,将非 ...
- Django:RestFramework之-------版本控制
6.版本控制 从URL通过get传参获取版本. 6.1自定义版本控制 from rest_framework.views import APIView class ParamVersion(objec ...
- DataPipeline CTO陈肃:构建批流一体数据融合平台的一致性语义保证
文 | 陈肃 DataPipelineCTO 交流微信 | datapipeline2018 本文完整PPT获取 | 关注公众号后,后台回复“陈肃” 首先,本文将从数据融合角度,谈一下DataPipe ...
- Cheat Engine 人造指针
打开游戏 查看内存区域 查看游戏当前使用的内存区域 下面这一段是游戏当前使用的内存区域,选择一片可以读写的内存区域 跳转到这片内存 查看是否有空余内存可以使用 使用空闲内存 我们选择0075DFD0开 ...
- Go基本运行编译命令解释
go run命令: 直接执行命令源码文件:一定要声明自己是在main包下,要是只有一个工作区,相应的文件就会存在bin文件下 go build: 把文件夹下的命令源码文件编译成直接运行文件,但是不能有 ...
- 【转】大众点评CAT开源监控系统剖析
https://www.cnblogs.com/yeahwell/p/cat.html 参考文档: 大众点评的实时监控系统分析(一) CAT_source_analyze 透过CAT,来看分布式实时监 ...
- C++学习(9)—— 对象的初始化及清理
1. 构造函数和析构函数 对象的初始化和清理是两个非常重要的安全问题 一个对象或者变量没有初始状态,对其使用后果是未知 同样的使用完一个对象或者变量,没有及时清理,也会造成一些安全问题 C ...
- Find the median(2019年牛客多校第七场E题+左闭右开线段树)
题目链接 传送门 题意 每次往集合里面添加一段连续区间的数,然后询问当前集合内的中位数. 思路 思路很好想,但是卡内存. 当时写的动态开点线段树没卡过去,赛后机房大佬用动态开点过了,\(tql\). ...