基于C++实现的操作系统二级文件系统设计

Monstarrr

发布日期: 2019-03-18 18:51:29 浏览量: 1477
评分:
star star star star star star star star_border star_border star_border
*转载请注明来自write-bug.com

1、题目介绍

名称:一个简单的用户级文件系统——设计和实现

实现下面的API:

  1. void ls(); // 列目录
  2. int fopen(char *name, int mode);
  3. void fclose(int fd);
  4. int fread(int fd, char *buffer, int length);
  5. int fwrite(int fd, char *buffer, int length);
  6. int flseek(int fd, int position);
  7. int fcreat(char *name, int mode);
  8. int fdelete(char *name);

要编写的是2个应用程序:

  • Initialize:初始化c:\myDisk.img

  • testMyFileSystem:接收用户输入的文件操作命令,测试文件系统和API

2、软件功能

实现了一个简单的二级文件系统,并实现了一个简单的Shell用来测试这个二级文件系统。

  • ls:列目录

  • cd:更改当前目录(支持绝对路径和相对路径)

  • md:创建文件夹

  • del:删除文件或文件夹

  • in:从真实磁盘上导入文件

  • out:将文件系统内的文件导出之真实磁盘

  • exit:shell的退出(一定要用这个退出否则有可能造成文件系统的损坏)

3、开发平台

本程序在VS2008下编译,但是没有使用.Net的库函数因此应该是在一般的机器上都能运行。

4、程序的配置与运行

Creatmyfilesystem是虚拟磁盘文件生成程序;mycmd是展示程序。

使用步骤

  • 将creatmyfilesystem和mycmd分别编译后将两个文件放入同一文件夹下

  • 先运行creatmyfilesystem.exe来创建二级文件系统mydisk.img

  • 后运行mycmd对文件系统进行测试

5、主要代码声明说明

  1. //MyDisk.h
  2. class MyDisk //模拟硬盘的行为及实现部分硬盘操作函数
  3. {
  4. private:
  5. fstream fs;
  6. bool op,changed;
  7. char buf[bsize];//高速缓存
  8. int bno;
  9. unsigned int fansize;
  10. public:
  11. void init()//初始化
  12. MyDisk()//构造函数
  13. bool Opened()//返回磁盘是否被打开
  14. void close()//关闭磁盘
  15. void open(char* filename,int mode=ios::out|ios::in|ios::binary)//打开磁盘
  16. unsigned int ftol(unsigned int fno,unsigned int off)//将扇区号和偏移转换成文件中的位置
  17. void updatefan()//更新当前扇区
  18. void readfan(unsigned int fno)//读扇区
  19. void writefan(unsigned int fno)//写扇区
  20. char readchar(unsigned int loc)//读字节(连续度相同扇区时不重复读扇区)
  21. void writechar(char c,unsigned int loc)//写字节(延迟写)
  22. void read(char *c,unsigned int size,unsigned int loc)//(读指定长度的数据)
  23. void write(char *c,unsigned int size,unsigned int loc)//(写指定长度的数据)
  24. void setbuf(char c,int x)//修改buf的值
  25. char getbuf(int x)//返回buf的值
  26. MyDisk(char* filename,int mode=ios::out|ios::in|ios::binary)//构造函数
  27. ~MyDisk()//析构函数
  28. };
  29. //MyINode.h
  30. class MyINode //i节点,由v6++修改而来部分结构没用上
  31. {
  32. public:
  33. unsigned int i_isdir; //用来表示该i节点所对应文件是否是目录
  34. int i_nlink; // 文件联结计数,即该文件在目录树中不同路径名的数量
  35. short i_uid; // 文件所有者的用户标识数 short i_gid; // 文件所有者的组标识数
  36. int i_size; // 文件大小,字节为单位
  37. int i_addr[10]; // 用于文件逻辑块好和物理块好转换的基本索引表
  38. int i_atime; // 最后访问时间
  39. int i_mtime; // 最后修改时间
  40. MyINode() //构造函数
  41. };
  42. //DirectoryEntry.h
  43. class DirectoryEntry //文件名与i节点号对应的数据结构,由v6++修改得到
  44. {
  45. public:
  46. static const int DIRSIZ = 28; /* 目录项中路径部分的最大字符串长度 */
  47. static const int size=DIRSIZ+4;
  48. public:
  49. int m_ino; /* 目录项中Inode编号部分 */
  50. char m_name[DIRSIZ]; /* 目录项中路径名部分 */
  51. DirectoryEntry::DirectoryEntry() //构造函数
  52. };
  53. //SuperBlock.h
  54. class SuperBlock//超级块由v6++修改得到
  55. {
  56. SuperBlock()
  57. public:
  58. int s_isize; /* 外存Inode区占用的盘块数 */
  59. int s_fsize; /* 盘块总数 */
  60. int s_nfree; /* 直接管理的空闲盘块数量 */
  61. int s_free[100]; /* 直接管理的空闲盘块索引表 */
  62. int s_ninode; /* 直接管理的空闲外存Inode数量 */
  63. int s_inode[100]; /* 直接管理的空闲外存Inode索引表 */
  64. int s_rootino; /*文件根目录i节点编号*/
  65. int s_flock; /* 封锁空闲盘块索引表标志 */
  66. int s_ilock; /* 封锁空闲Inode表标志 */
  67. int s_fmod; /* 内存中super block副本被修改标志,意味着需要更新外存对应的Super Block */
  68. int s_ronly; /* 本文件系统只能读出 */
  69. int s_time; /* 最近一次更新时间 */
  70. int s_icount; //i节点总数
  71. int s_bcount; //一般盘块总数
  72. int padding[44]; /* 填充使SuperBlock块大小等于1024字节,占据2个扇区 */
  73. };
  74. //MyFileSystem.h
  75. class SList//虚实映照表辅助结构
  76. {
  77. public:
  78. int no;
  79. int a[64];
  80. int b[64];
  81. MyFileSystem *fs;
  82. void clear()
  83. SList()
  84. void linkfs(MyFileSystem *mfs);
  85. void save()
  86. void open(int bno);
  87. void saveto(int bno);
  88. };
  89. class MyFileSystem//文件系统
  90. {
  91. public:
  92. static const int lsu=1;//超级块起始块编号
  93. static const int lbi=lsu+2;//第0块inode块编号
  94. static const int iel=8;//一块几个i节点
  95. static const int rootino=0;//
  96. //static const int small=6;
  97. static const int sa=4;
  98. static const int mo=bsize/sa/2;
  99. static const int om_opened=1;
  100. static const int om_in=2;
  101. static const int om_out=4;
  102. static const int om_trunc=8;
  103. static const int om_app=16;
  104. char *name;
  105. MyDisk d;
  106. unsigned int put,get,omode;
  107. MyINode myi;
  108. int myin;
  109. bool op;
  110. //bool ichanged;
  111. SuperBlock su;
  112. MyFileSystem()//构造函数
  113. ~MyFileSystem()
  114. void init()//初始化
  115. void close()//关闭文件系统
  116. void open(char *c)//打开文件系统
  117. MyFileSystem(char *c)//构造函数
  118. unsigned int bloc(unsigned int bno)//返回指定数据块的起始地址
  119. bool freeb(int bno)//将制定编号的块加入空闲块栈
  120. int allocb()//分配空闲块
  121. unsigned int iloc(unsigned int ino)//返回指定i节点的起始地址
  122. bool freei(int ino)//将指定i节点加入空闲i节点栈
  123. int alloci()//分配空闲i节点
  124. void openi(int ino,int mode=om_in|om_out)//打开指定编号的i节点
  125. void creati(int ino,int mode=om_in|om_out)//初始化指定编号的i节点
  126. void updatei()//更新当前i节点
  127. void closei()//关闭当前i节点
  128. unsigned int bmap(int bno)//虚实地址映照
  129. void addb(int bno)//向文件末尾加入数据块
  130. void remb(int bno)//去除文件末尾的数据块
  131. void setisize(unsigned int newsize)//改变文件大小并修改文件数据块
  132. void iread(char* c,unsigned int size,int loc)//读取文件指定位置(虚空间)的指定长度数据
  133. void iwrite(char* c,unsigned int size,unsigned int loc)//写入文件指定位置(虚空间)的指定长度数据
  134. void fread(char* c,unsigned int size)//读取get指针指向位置指定长度的数据
  135. void fwrite(const char* c,unsigned int size) //写入put指针指向位置指定长度的数据
  136. void seekp(int loc)//指定get指针位置
  137. void seekg(int loc)//指定put指针位置
  138. int openfileat(const char *c)//打开指定文件路径的i节点
  139. void creatfile(const char *c,unsigned int isdir=0)//在当前路径建立指定文件名的文件
  140. void creatname(const char *c,int ino)//为指定i节点建立指定文件名
  141. void creatfileat(const char *c,unsigned int isdir)//在指定路径建立文件
  142. void deletei(int ino)//删除指定i节点对应文件
  143. int deletenameat(const char *c)//删除指定路径的文件
  144. void fcreat(const char *c,unsigned int isdir=0,int mode=om_in|om_out)//创建文件并指定打开方式
  145. int fopen(const char *c,int mode=om_in|om_out)打开文件并指定打开方式
  146. void fclose()//关闭文件
  147. void fdelete(const char *c)//删除文件
  148. bool eof()//get是否到达文件末尾
  149. void CreatMyDisk(char *c,int ln)//生成文件系统函数
  150. };

6、运行截图

7、介绍与感想

7.1 解决的问题及方法

我这个程序编写的是单任务二级文件系统,我这个程序模拟了硬盘的扇区逻辑没有利用文件读写的便利之处,这样做的优点是只要更改myDisk类下的readfan()和writefan()函数将其链接到真正的磁盘操作程序就可以变成磁盘上的一级文件系统,但是采用扇区逻辑也有缺点那就是读写一定要以扇区为单位,这样就做了许多无用操作减缓操作速度。我认为这个程序的最大亮点是我自己设计了一个文件虚实映照表结构,老师给的UNIXv6++单个文件大小不超过16m我这个虚实映照表结构理论上不限制单个文件大小,但是受地址编号的限制单个文件最大不超过MaxInt32字节,约2GB,由于对大文件读写过于耗费时间所以我没有对大文件读写进行测试,最大测试文件800kb,该虚实映照表采用以下结构:i节点中有编号为0-9的虚实因照表表项,我用0-8直接指向物理盘块第9块指向二级映照表所在盘块,从而级映照表所在盘块开始每各盘块可以记录512/4=128条记录,其中我用0记录该盘块指向的盘块数,1-63直接指向物理盘块,64-128指向下级映照表,该结构其实是一个64叉字典树,只要将虚空间盘块号减8后转为64进制数就可以得道该盘块在虚实映照表中的位置从而找到物理盘块。我这个程序在磁盘读些上虽然没有引入缓存的结构,但是充分利用了磁盘高速缓存(该程序中的磁盘及其高速缓存是软件模拟的)采用了延迟写的方式,尽可能减少磁盘的读写。

我这个程序的中的展示部分是一个自己写的shell程序它具有以下命令:

  • ls:列目录

  • cd:更改当前目录(支持绝对路径和相对路径)

  • md:创建文件夹

  • del:删除文件或文件夹

  • in:从真实磁盘上导入文件

  • out:将文件系统内的文件导出之真实磁盘

  • exit:shell的退出(一定要用这个退出否则有可能造成文件系统的损坏)

除此之外的命令将被视为执行exe应用程序,执行应用程序的实现方法是将文件导出到临时文件夹并在windows下运行,运行后删除临时文件夹。

7.2 课程设计的感受

在这一次课程设计中,我感觉到了自己能力上的欠缺,原本我认为我对类与对象理解已经相当不错了,但是这一次课程设计由于涉及到磁盘操作我就乱了阵脚,没能坚持用面向对象的思想进行编程,导致这个程序的类对象封装性不是特别好,许多地方近似于面向过程的编程,这使我在调试的时候遇到了较大的困难,不过费了九牛二虎之力最终还是大体调试完成,这锻炼了我调试程序特别是调试与文件相关的程序的能力,因此这一次课程设计对于我来说是相当有意义的,在认识到自己的差距之后,我要更加努力学习,让自己的能力更上一层楼。

上传的附件 cloud_download 基于C++实现的操作系统二级文件系统设计.7z ( 213.66kb, 18次下载 )
error_outline 下载需要9点积分

发送私信

摘不到的星星,总是最闪亮的

11
文章数
12
评论数
最近文章
eject