视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
模拟文件系统实验报告
2025-09-30 19:50:50 责编:小OO
文档
操作系统大型试验

姓名:XX

班级:软件工程110x

学号:*********xxx

一、名称

    操作系统大型试验。

二、目的

用C++编写出一个简单的模拟文件系统,实现目录的添加、删除、重命名,文件的添加、删除、重命名、文件和目录、文件的拷贝。

三、要求

开发工具:word,vc win32api

1.设计和实现一个简单的文件系统,要求包括目录、普通文件和文件的存储

2.文件系统的目录结构采用类似Linux的树状结构;

3.要求模拟的操作包括:

a)目录的添加、删除、重命名;

b)目录的显示(列表)

c)文件的添加、删除、重命名

d)文件和目录的拷贝

4.用户进入时显示可用命令列表;用户输入help时显示所有命令的帮助文档; 输入某个命令+?时显示该条命令的使用说明

5.用户输入exit时退出该系统

6.实验实现基于windows平台;

7.实验开发语言可以选用C/c++等

四、设计

1.主要思路说明

本模拟系统通过一个大小固定的数组要代表物理盘块,假设共有1024块,新增目录占一块,新增文件占一块,文件中可输入内容,内容假设定义为5个字符占一块,超出则应新申请空间。模拟物理盘块的数组中,数组内容为-99代表改物理盘块内容为空,可使用,其他数字均代表该物理盘块被占用,其中-3代表是占用文件的末结点,其他整数代表是文件内容的下一个寻址下标,另有一个string类型的数组来存储内容,模拟文件写入了对应下标的物理盘块中。设置了一个全局指针指向根结点,一个全局指针指向当前操作目录。搜索空白物理盘块时采用顺序搜索物理盘块数组。存储形式主要采用类似二叉树结构,如目录为根,目录下的第一个文件或目录存在根的子节点,目录下的其他文件或目录存在第一个文件或目录的兄弟节点,以此类推。

本程序仅seperate()函数使用现成代码,此函数功能为将输入命令串分离,仅仅起到美观作用,其余所有代码均为原创!

2.申优功能:

1)能实现动态增长,即当输入文件的内容大小大于分配的模拟物理盘块时系统能够自动寻找空物理盘块并分配,将超出的内容保存在新的物理盘块中,若超出模拟磁盘大小,则超出部分不保存且返回提示。

2)能实现级联删除,即当删除目录(文件夹)时,目录下的所有内容也应当删除并正确释放物理盘块空间。

3)能实现目录的复制,即复制目录时(文件夹)时,该目录下的所有文件和目录也应准确复制至目标目录中,并正确分配物理盘块空间。

3.主要函数和类的定义

  1)主要函数定义

     #define show_bnum 20   //显示物理盘块的块数

#define block_size 1024   //物理盘块块数

int block[block_size];    //假设有block_size块物理盘块

string content[block_size];  //存放文件内容

int Msize=5;     //此处为模拟磁盘大小为输入5个字符

fnode *root=new fnode("WP:",0,0);  //设置根目录

fnode *current_path=new fnode();    当前路径

fnode *seek_flag=new fnode();    //作为查找标志

fnode *cp_flag=new fnode();     //作为复制的位置标志

void initialize();        初始化

int seekTarget(string name);     //搜索文件或目录

int seek_log(string name);     //搜索目录

void delete_node(string name);    //删除节点

int freeblock(fnode *);      //释放物理盘块

int seekfreeblock();       //搜索可用物理盘块

void show_current_path();     //显示当前路径

void add_file(string name,int t);    //增加目录、文件

void show_curpath_all();      显示当前目录下的所有文件

void rename_file(string Oname,string Nname); //重命名

void seperate();        分离命令

void cd();         //进入目录

void add_File();        增加文件功能入口

void add_Log();        增加目录功能入口

void delete_file();       //删除文件或目录功能入口

void show_memory();      //显示物理盘块占用情况

void re_name();        重命名功能入口

void help();        //查看帮助

void show_content();      //查看文件内容

void write_file();       //写文件

void Clear_();        //清屏

void Exit();         退出

void cp();         //复制功能入口

void cp_log(fnode *target,fnode *source);  //复制目录

void cp_file(fnode *target,fnode *source);  //复制文件

void cp_node(fnode *target,fnode *source);  //复制节点

int find_target_log();       找到复制的目标目录

int calculate_logsizeMain(fnode *);    计算目录大小

int calculate_logsize(fnode *);

2)文件节点类的定义:

class fnode 

{         

public:

  string filename;     文件名

  int type;    //文件类型,1为普通文件,0为目录文件

  fnode *parent;     父节点

  fnode *child;      子节点

  fnode *brother;     兄弟节点

  int block_num;     表示占用的物理盘块块号

  int isBro;    //表示是否是在同级目录下,0表示不是,1表示是

  int isCld;    //是否为目录下第一个节点,1表示是,0表示不是

  fnode()       初始化

  {

   type=-1;

   parent=NULL;

   child=NULL;

   brother=NULL;

   block_num=-1;

   isBro=0;

   isCld=0;

  }

  fnode(string n,int t,int b)   //根节点初始化

  {

   type=t;

   filename=n;

   parent=NULL;

   child=NULL;

   brother=NULL;

   block_num=b;

   block[block_num]=-3;

   isBro=0;

   isCld=0;

  }

  fnode(fnode *p,string name,int t,int b) //文件节点初始化

  {

   parent=p;

   filename=name;

   type=t;

   child=NULL;

   brother=NULL;

   block_num=b;

   block[block_num]=-3;

   isBro=0;

   isCld=0;

  }

  void copy(fnode *cp)    //拷贝函数

  {

   filename=cp->filename;

   type=cp->type;

   parent=cp->parent;

   child=cp->child;

   brother=cp->brother;

   block_num=cp->block_num;

  }

 };

4.命令:

命令解释
echoecho命令可以在当前目录下创建一个文件,具体格式:echo+name

mdmd命令可以在当前目录下创建一个目录文件,具体格式:md+name

deldel命令可以在当前目录下删除一个已存在的文件或目录(支持级联删除),具体格式:del+name

cdcd命令可以进入下一级目录或返回上级目录、根目录,具体格式:cd+name或cd+.或cd+..

cpcp命令可以复制当前目录下一个指定的文件或目录至指定的目录,具体格式:cp+name+road

dirdir命令可以显示当前目录下的所有文件和目录,具体格式:del

renren命令可以重命名一个存在于当前目录下的文件或目录,具体格式:ren+name  +new name

typtyp命令可以查看当前目录下一个文件的内容,具体格式:typ+name

wrtwrt命令可以在当前目录下写内容至一个已存在的文件,具体格式:wrt+name +content

memmem命令可以查看模拟物理盘块的使用情况,具体格式:mem

clscls命令为清屏命令,具体格式:cls

exitexit命令为退出命令,具体格式:exit

五、关键技术流程图及说明

提示:若图中文字无法看清,可用Micorsoft Visio打开压缩包下“部分程序流程图”文件夹的绘图文件查看。

1.增加文件或目录(此功能比较简单,流程图写的较详细就不做说明):

2.删除目录(实现级联删除):

说明:删除目录时删除文件和删除目录本身放在同一个函数中,删除目录下的所有文件放在freeblock函数里,这样比较好处理。下面给只给出递归函数的流程图。

3.将内容写入文件(实现动态增长):

说明:图中Msize为模拟规定的文件块字符串大小,比如Msize=5,那么一个物理盘块只能存5个字符,超出则要申请新的空间。主要采用双重循环方法写入,外层循环为需要的块数,内层循环为Msize,用string累加字符串内容,内层循环退出后新申请一个空间并将对应下标赋给上一个物理盘块数组,再将对应内容存入content(为string类型的数组,模拟存储内容)数组中,直至退出外层循环。

4.复制目录:

说明:这里和删除目录一样,写了两个复制函数,这样写同样因为递归调用是比较方便,第一个函数传入参数为目标目录指针和被复制的目录的指针,第一个函数里新建了一个阶段复制被复制的目录的内容,然后将新建节点的子节点和被复制目录的子结点传入下一个递归调用函数(因为目录的内容存于目录的子节点,与兄弟节点无关),第二个函数就是递归调用函数cp_node,下面就只给出cp_node的流程图(复制之前同样进行了路径的判误操作,内存大小的判断操作,是否重名的判断操作,被复制目录是否存在判断操作,这些操作在递归函数之前完成,所以下面的递归函数不体现这些操作)。

六、运行结果

1.主界面展示:

图:主界面展示

2.help命令展示:

图:help命令展示

 3.echo命令展示:    

图:echo命令展示

 4.del命令展示:

图:del命令展示-普通删除

  说明:创建了目录log1,在log1中创建一系列文件和目录,磁盘使用情况显示已分配,实用del删除命令后查看磁盘分配证明级联删除是可靠的。

图:del命令展示-级联删除

5.md命令展示:

图:md命令展示

6.cd命令展示:

  说明:图中展示了cd+name、cd+.、cd+..三种cd命令的使用和判别情况。

图:cd命令展示

 7.dir命令展示:

图:dir命令展示

 8.typ命令展示:

图:typ命令展示

  9.ren命令展示:

图:ren命令展示

 10.wrt命令展示:

图:wrt命令展示

说明:此处为了实验方便,将磁盘大小限定为5,每块磁盘输入的字符数限2,输入的内容11223344556677需要9块磁盘块,而磁盘块为5,根目录占用一块,只能输入4块大小的内容,即11223344,所有文件file只写入了11223344 。

图:wrt动态增长展示

 11.mem命令展示:

图:mem命令展示

  12.cls命令展示:

图:cls命令展示-1

图:cls命令展示-2

 13.cp命令展示:

说明:图中根目录(WP:)下创建了目录a(md a)、目录b(md b),在a目录下创建了b目录(md b),在b目录中创建了文件a(echo a)、目录c(md c),文件a中输入1111122222(wrt a 111112222)内容代表占了两块物理盘块(程序中Msize模拟大小,设为5个字符了),再进入目录c(cd c),c中先创建目录f(md f)再创建文件g(与之前创建顺序不同说明程序在不同情况下能正常运行),在g中输入5个3,5个2,5个1(wrt g 333332222211111)代表占用3块物理盘块空间,再返回目录a(cd . cd .),将目录a下的目录b复制给目录WP下的目录c(cp b WP:\\c),再将目录a中的目录b删除(del b证明的确是复制而非简单指针指向),进入WP下的目录c查看刚复制的内容(dir)。物理盘块使用情况中第一个-3为根目录占用,第二个-3是目录a,第三个-3是目录c,接下来的8个-99是目录a中原目录b占用的空间(此处证明删除是可靠的),图中显示目录c中确实成功复制了目录b及目录下的所有内容(使用dir命令查看)。

图:cp命令展示

14.exit命令展示:

图:exit命令展示

 15.综合展示:

说明:echo a在根目录(WP:)下创建了文件a,md b在根目录(WP:)下创建了目录b,dir显示根目录下的所有文件和目录,wrt a aaaaabbbbbccccc在文件a中输入了一串内容,typ a显示文件a中的内容,cd b进入目录b,md a在目录b下创建了目录a,cd a进入目录a,cd .返回目录b,cd .返回根目录WP:,ren b newname将目录b重命名为newname,mem显示内存情况,第一个-3代表根节点占用,第二个3代表文件a占用且下一块盘块下标为3,第三个-3代表目录b占用,之后的4代表被文件a占用且的下一块盘块的寻找下标为4,下一个-3代表文件a的末盘块,下一个-3代表目录b内的目录a占用,del a在根目录WP:下删除文件a,mem查看物理盘块实验情况,图中显示原文件a占用的内存空间已经变为-99,代表成功删除a并释放磁盘空间(-99代表磁盘空间空闲可用),dir显示根目录WP:下所有文件和目录,显示只有newname,则证明重命名和删除操作是成功的。

图:综合展示

七、心得体会和调试中遇到的问题及解决办法

编写调试过程中遇到许多问题,一类是指针指向空还继续操作造成程序停止运行,经检查后修改正确,一类是逻辑上出现错误导致级联删除或者目录复制出错,经改正后成功实现。

主要的难点在于兄弟结点和子结点的处理,所以再程序中引入了isBro这个标志位来判断是否是兄弟结点即与父节点是否在同级目录,若不在同级目录则父节点为真父节点(是指向本目录而非本目录中上个文件)。还有一个难点是在进行递归调用删除或复制目录时发现处理目录和目录下的内容不太合适放在同一个递归程序中,所以单独写了两个函数处理目录的复制或删除,然后对应两个递归程序处理目录下的所有内容。

实验总结及有待改进的问题。

因为时间比较紧张,在几门考试中抽空写了这个小程序,所以并没有实现存盘,另因为对输入命令字符串的处理上有点瑕疵,所有在写文件内容中只能写入连续的字符串(中间不能插入空格),否则会被判定为命令输入错误,并且只实现了文件的写入,不能修改或插入,有待改进。没有实现目录树的展示,只能显示目录下所有文件,有待改进。但相信时间再充裕一些这些小问题都能很好地解决。

八、源代码

在压缩包内“源代码”文件夹内。下载本文

显示全文
专题