基于内存一个类似Unix文件管理系统的C++实现

  这是一个课设项目,网上看到的都是某于FAT32的代码,笔者就想写一个混合索引的文件管理系统。

题目要求如下:;}

任务:建立基于内存的文件系统

目的:深入了解文件系统结构

要求:首先分配一定容量的内存,建立虚拟磁盘;

在该磁盘上建立相应的文件文件系统;

为该文件系统设计相应的数据结构来管理目录,虚拟磁盘的空闲空间,已分配空间等;

提供文件的创建、删除、移位、改名等功能;

提供良好的界面,可以显示磁盘文件的状态和空间的使用情况;

提供虚拟磁盘转储功能,可将信息存入磁盘,还可从磁盘读入内存。

原理及算法描述

使用unix系统中使用的混合索引方式,在一固定大小内存区内建立相应系统。文件系统空间分配如下

其中,超级块用来存放整个文件系统的信息,文件节点区用来存放文件/目录的inode信息,目录项区用来存放目录项及相应信息,文件存储区用来存储具体文件内容。

系统启动时,首先初始化整块虚拟磁盘空间,为其设置好相应超级块信息,初始文件节点及初始文件目录,并清空整场文件存储区。

建立文件:建立文件时,通过当前目录,找到相应的目录的节点编号,搜索一个未使用的文件节点,设置其相关信息,并将其添加到相应目录项中,目录项数加一;

建立目录:和建立文件相似,只是将新申请的文件节点类型设置为目录,并申请一个请的目录项,在文件节点中设置新目录号,目录项数加一。

删除目录:通过路径找到指向目录的节点,匹配到要删除的目录,获得其文件节点号,清空其内容,归还给系统,然后清空该目录信息,归还系统,相应目录数量减一;

删除文件,和删除目录项相关,但需要将其文件节点指向的盘块归还系统。

移动文件或目录:找到其相应节点,将原指向它的信息删除,并把将它添加到新目录的目录项中;

改名:找到指定文件节点,搜索新文件名是否重名,不重名,则将指定文件的名称项进行更改;

写文件:找到文件节点,计算文件大小,确定所需块数并确定索引级数,申请相应的空闲块,将内容其添加到文件节点地址区,将内容顺序定入相应盘块中。

开发环境

Windows 10+Visual Studio 2015

图片1.png

文件索引方式图

主要算法

根据路径获得节点号:(int getnode(char *path))整个文件系统在使用时,已经形成一个类似树形的文件目录,寻找节点时,只需要按路径名一级一级进行广搜即可,只要在到达最终目录前有不匹配,则路径为非法路径;返回-1。

创建目录:(STATUS mkdir(char *path, char* pname)):在指定的路径(path)下创建一个名为pname的目录,先找到一人空闲目录块和空闲文件节点

// 从起始位置,寻找空闲块,并申请使用

for (int i = 0; i < DIRSIZE; i++)

{

if (root->dir[i].size == 0)

{

root->dir[i].size = 1;

d_ino = i;

break;

}

}

//寻找空间文件节点,并设置相关信息

for (int i = 0; i < NUM; i++)

if (root->fnode[i].fi_nlink != 1)

{

n_ino = i;

root->fnode[i].fi_mode = DIRMODE;

root->fnode[i].fi_size = 0;

root->fnode[i].dir_no = d_ino;

root->fnode[i].fi_addr[0] = NULL;

root->fnode[i].fi_nlink = 1;

break;

}

// 在你节点建立相应指针(数组下标)指向新节点

for (int i = 0; i < DIRSIZE; i++)

{

if (strlen(root->dir[root->fnode[ino].dir_no].direct[i].d_name) == 0)

{

root->dir[root->fnode[ino].dir_no].direct[i].d_ino = n_ino;

root->dir[root->fnode[ino].dir_no].size++;

strcpy(root->dir[root->fnode[ino].dir_no].direct[i].d_name, pname);

break;

}

}

删除目录:(STATUS rm(char *path, char *file)) 过程和创建文件洽好相反,即先找到节点,将其从父目录项中删除,并删除该节点

重命名:(STATUS rename(char *path, char *cname, char *nname))实现比较简单,找到对应的目录项,更改其名字即可,其中,特别注意要检查新文件是否重名。

实现效果

现关代码已经上传到GitHub,地址 FileSystem

0 条评论
发表一条评论