操作系统模拟unix文件系统实验报告要点Word格式.docx
- 文档编号:21805913
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:42
- 大小:1.92MB
操作系统模拟unix文件系统实验报告要点Word格式.docx
《操作系统模拟unix文件系统实验报告要点Word格式.docx》由会员分享,可在线阅读,更多相关《操作系统模拟unix文件系统实验报告要点Word格式.docx(42页珍藏版)》请在冰豆网上搜索。
0#块可省略
I节点栈及空间为20项
块大小为512字节
卷盘块数大于100
I节点盘块数大于10块
(2)I节点结构设计
文件大小
文件联接计数
文件地址
文件拥有者
文件所属组
文件权限及类别
文件最后修改时间
其中文件地址为六项:
四个直接块号,一个一次间址,一个两次间址
(3)目录结构
用16字节表示,其中14字节为文件名,2字节为I节点号
(4)用户及组结构
用户信息中包括用户名、口令,所属组,用户打开文件表
(5)文件树结构
除(4)要求外,适当考虑UNIX本身文件树结构
(6)实现功能
Ls显示文件目录
Chmod改变文件权限
Chown改变文件拥有者
Chgrp改变文件所属组
Pwd显示当前目录
Cd改变当前目录
Mkdir创建子目录
Rmdir删除子目录
Mv改变文件名
Cp文件拷贝
Rm文件删除
Ln建立文件联接
Cat连接显示文件内容
Vi文件写入
Mk创建文件
umask查看用户屏蔽码
Umask文件创建屏蔽码
Passwd修改用户口令
Ls-l查看文件类型
Login用户注销
Logout退出系统
Help显示帮助信息
二、实验环境
实验设备:
MicrosoftVisualStudio2010
开发语言:
c++
三、实验设计
1.数据结构设计
磁盘文件结构设计:
用一个名为disk.txt的文件模拟Unix系统磁盘,总共分为200块,每块514个字节(实际可用512个字节,还有2个字节是磁盘分割符‘\n’),使第一块(0#)盘块做为超级块,记录该系统磁盘的使用情况;
第二块(1#)盘块——第十三块(12#)盘块作为存储I结点使用,每个I结点74个字节,所以每个盘块可以存放6个I结点,总共有72个I结点,记录在超级块中;
十三块(12#)以后的盘块作为存储文件内容使用,总共187个盘块,用成组连接法记录在超级块中。
对于I结点的具体设计如下:
classINode//(74B)
{
public:
intfsize;
//文件大小setw(6)
intfbnum;
//文件盘块数setw(6)
intaddr[4];
//四个直接盘块号文件最大为4*512=2048=2KBsetw(4)*4
intaddr1;
//一个一次间址()文件大于2KB,小于2KB+16*512=10KBsetw(4)
intaddr2;
//一个两次间址()文件大于10KB,小于10KB+16*16*512B=138KBsetw(4)
charowner[6];
//文件拥有者setw(6)
chargroup[6];
//文件所属组setw(6)
charmode[12];
//文件类别及存储权限setw(12)
charctime[10];
//最近修改时间setw(10)
intconnect;
//文件联接计数
};
对于超级块的具体设计如下:
classsuperBlock
intFIStack[72];
//空闲结点号栈setw(3)*72
intFICount;
//空闲i结点总数setw(3)
intFIPtr;
//空闲结点栈指针setw(3)
intFBStack[10];
//空闲盘块号栈setw(4)*10
intFBCount;
//空闲盘块总数setw(4)
intFBPtr;
//空闲盘块栈指针setw(3)
初始化磁盘示意图:
14#
13#
1
2
除了超级块、I结点、磁盘文件的数据结构设计以外,为了系统操作方便,我还设计了用户类、文件目录类。
用户类具体设计:
classUSER//用户(24B)
charname[6];
//用户名setw(6)
charpass[6];
//密码setw(6)
//所属组setw(6)
intumask[3];
//用户umask码setw(6)
用户信息全部存放在一个user.txt的文件里面,所以对于user.txt文件也有一个设计,文件最开始是存放用户总数(setw(6)),随后跟着的是每一位用户名、密码、所属组、用户umask码。
文件目录类具体设计:
classCatalog//目录项(18B)
charfname[14];
//文件名setw(14)
intindex;
//i结点号setw(4)
目录信息全部都存放在disk磁盘里面,所以具体数据结构设计都在上面的磁盘文件设计中提及。
2.程序流程设计
◆系统主体流程图设计见图1
◆用户注册流程图见图2
◆登陆功能流程图见图3
◆用户修改口令流程图见图4
◆用户umask码修改流程图见图5
◆显示所有子目录ls操作流程图见图6
◆创建文件mk、目录mkdir流程图见图7
◆删除文件rm流程图见图8
◆删除目录文件rmdir流程图见图9
◆改变当前路径cd操作流程图见图10
◆查看文件内容cat操作流程图见图11
◆拷贝文件、目录cp操作流程图见图12
◆建立文件联接ln操作流程图见图13
◆修改文件名称MV操作流程图见图14
◆修改文件权限chmod操作流程图见图15
◆修改文件拥有者chown、所属组chgrp操作流程图见图16
◆写流程图vi见图17
N
Y
cd[enter].[enter]切换到当前目录
cd[enter]/[enter]切换到根目录
cd[enter]..[enter]切换到父目录
cd[enter]dir[enter]切换到某一子目录,dir为子目录名
cd[enter]string[enter]切换到指定路径的目录,string为路径
mkdir[enter]dir[enter]当前目录下创建名为dir的子目录
rmdir[enter]dir[enter]删除当前目录下名为dir的子目录
mk[enter]file[enter]当前目录下创建名为file的文件
rm[enter]file[enter]删除当前目录下名为file的文件
cp[enter]dirORfile[enter]string[enter]拷贝当前目录下文件或子目录到指定路径下
cat[enter]file[enter]查看当前目录下名为file的文件内容
vi[enter]file[enter]向当前目录下名为file的文件写入一定内容
pwd[enter]显示当前目录
ls[enter]显示所有子目录
chmod[enter]file[enter]改变当前目录下名为file文件的权限
chown[enter]file[enter]改变当前目录下名为file文件的拥有者
chgrp[enter]file[enter]改变当前目录下名为file文件的所属组
MV[enter]file[enter]改变当前目录下名为file文件的文件名
login[enter]用户注销,可以重新登陆
passwd[enter]用户改变密码
umask[enter]查看用户umask码
Umask[enter]code[enter]修改用户umask码为code
ln[enter]file1[enter]file2[enter]文件file1与file2建立连结
ls-l[enter]file[enter]查看文件file的类别
help[enter]提供帮助
logout[enter]退出系统
四、模块详解
1.文件操作
◆mk创建文件模块,输入mk命令,回车,输入文件名,回车,即会在当前目录文件下创建一个名为刚刚输入的文件名的数据文件。
在该创建过程中首先要判断该目录中有没有同名的文件,如果有的话就创建失败,还要判断在该目录下有没有创建文件的权限,有权限才可以创建。
具体流程图查看第二节,系统流程图设计部分。
◆rm删除文件模块,输入rm命令,回车,输入文件名,回车,即会在当前目录文件下删除一个名为刚刚输入的文件名的数据文件。
在该删除过程中要判断该目录中是否存在该文件,如果不存在就没有必要执行该操作了,还要判断在该目录下有没有删除文件的权限,有权限才可以删除。
◆mkdir创建目录文件模块,输入mkdir命令,回车,输入文件名,回车,即会在当前目录文件下创建一个名为刚刚输入的文件名的目录文件。
◆rmdir删除目录文件模块,输入rmdir命令,回车,输入文件名,回车,即会在当前目录文件下删除一个名为刚刚输入的文件名的目录文件。
在该删除过程中要判断该目录中是否存在该目录文件,如果不存在就没有必要执行该操作了,还要判断在该目录下有没有删除文件的权限,有权限才可以删除。
删除的时候要判断该目录是否为空,如果里面有内容,则要通过递归函数,将他们一并删除了。
◆cp拷贝文件模块,输入cp命令,回车,输入要拷贝文件的文件名,回车,输入要拷贝到哪个路径下面,即会在该路径下创建一个名为与被拷贝文件名相同的数据文件(目录文件),并且指向盘块里面的内容都相同的数据文件(目录文件)。
在该拷贝过程中要判断该目录中是否存在该文件,如果不存在就没有必要执行该操作了,还要判断在该目录下有没有拷贝文件的权限,有权限才可以拷贝。
然后要查看该路径是否存在,存在该路径才可以在该路径下创建拷贝过来的文件,具体流程图查看第二节,系统流程图设计部分。
◆cat显示文件内容模块,输入cat命令,回车,输入文件名,回车,即会在屏幕上显示该文件的具体内容。
在该过程中要判断该目录中是否存在该文件,如果不存在就没有必要执行该操作了。
执行操作时,要调用readfile(INodeinode)函数,先读入文件内容到content里面,然后直接输出。
◆ls显示当前目录下所有目录的模块,输入ls命令,回车,即会在屏幕上显示当前目录下的所有目录。
在该过程中要判断该目录中是否为空,如果为空就没有必要执行该操作了。
执行操作时,要调用readdir(INodeinode)函数,先读入文件内容到content里面,然后直接输出。
如果子目录里面还有子目录,则通过递归,一并输出来。
◆pwd显示当前目录的模块,输入pwd命令,回车,即会在屏幕上显示当前所在的目录。
◆vi写文件操作模块,输入vi命令,回车,输入文件名,回车,既可以选择自己输入内容还是系统自动输入,选择自己输入的话,可以自己主动随便输入什么内容然后回车。
如果选择系统自动输入,那么还需要输入要填充的字符个数,系统就会自动填充。
◆chmod改变文件权限模块,输入chmod命令,回车,输入文件名,回车,即会根据不同类别的用户在屏幕上提示要改变哪一类用户的权限。
如果是文件拥有者执行该操作,他可以选择修改自己、其他用户的权限;
如果是文件所属组成员执行该操作,他可以选择修改自己、其他用户的权限;
如果是其他用户执行该操作,他只能选择修改自己的权限;
执行操作时,要判断对该文件有没有执行写操作的权利,没有就不能进行。
◆chown改变文件所有者模块,输入chown命令,回车,输入文件名,回车,就会判断执行者对于该文件有没有改变的权限,没有的话就不能执行,还有判断当前目录下有没有该文件,没有的话就没有必要执行该操作。
判断可以执行时,就会提示输入改变以后的所有者,然后判断输入的用户名的合法性,判断合法则修改成功。
(如果修改的文件时目录文件,则将它下面的文件全部一起改了)具体流程图查看第二节,系统流程图设计部分。
◆chgrp改变文件所属组模块,输入chgrp命令,回车,输入文件名,回车,就会判断执行者对于该文件有没有改变的权限,没有的话就不能执行,还有判断当前目录下有没有该文件,没有的话就没有必要执行该操作。
判断可以执行时,就会提示输入改变以后的所属组,然后判断输入的组名的合法性,判断合法则修改成功。
◆MV改变文件名模块,输入MV命令,回车,输入文件名,回车,就会判断执行者对于该文件有没有改变的权限,没有的话就不能执行,还有判断当前目录下有没有该文件,没有的话就没有必要执行该操作。
判断可以执行时,就会提示输入改变以后的文件名,然后判断输入文件名是否与当前目录下有重名的,判断没有重名则修改成功。
◆ln建立文件联接模块,输入ln命令,回车,输入要建立联接文件的文件名,回车,输入要连接到哪个文件的文件名,即会在该路径下创建一个以此命名的数据文件,并且该文件名后面的I结点号与前面一个文件的I结点号相同,指向相同的盘块。
在该过程中要判断该目录中是否存在该文件,如果不存在就没有必要执行该操作了,还要判断在该目录下有没有拷贝文件的权限,有权限才可以拷贝。
然后要查看该文件的重名是否存在,存在则建立联接失败,具体流程图查看第二节,系统流程图设计部分。
◆ls-l显示文件类型模块,输入MV命令,回车,输入文件名,回车,则会在屏幕上输出该文件的类型是目录文件还是数据文件。
◆cd改变当前所在目录的模块。
输入cd,回车,相应的字符串,回车,则会根据输入字符串的不同跳转到不同的目录下。
如果字符串是‘.’,则到当前目录;
如果字符串是‘..’,则到父目录;
如果字符串是‘/’,则到根目录;
如果字符串是当前目录下的子目录,则到该子目录;
如果字符串是一个决定路径,则到该绝对路径。
当然在执行的时候要判断有没有该子目录或者该绝对路径,如果没有的话,就不能执行。
2.用户操作
◆login用户注销模块,输入login,回车,当前用户就退出了,需要重新登录。
◆passwd用户修改口令模块,输入passwd,回车,则会提示输入原始密码,输入正确了才可以提示输入新密码,并且要求新密码输入两次,两次一样了才能通过修改密码成功。
◆umask用户查看umask码模块,输入umask,回车,屏幕上就会显示当前用户的用户umask码。
◆Umask用户修改umask码模块,输入Umask,回车,输入新的umask码,回车,既可以更新原有的用户屏蔽码。
◆logout用户退出系统模块,输入logout,回车,系统自动退出。
◆help用户寻求帮助模块,当用户不清楚执行命令的时候,可以输入help,回车,屏幕上会显示出各种命令语句。
五、实验演示
1.初始化磁盘块
超级块与I结点初始化结果截图:
成组连接法每10个盘块一组,最后一组只有7个,空闲盘块截图:
2.用户登录
直接登录:
注册登录:
注册以后用户文件里面已经有新用户的记录:
3.目录操作
新建目录:
新建以后可以看到盘块中已存在这两个目录:
这两个目录的i结点分配情况:
删除目录:
删除操作以后目录中aa目录项已经被删除:
删除操作以后aa文件的i结点结点也被回收:
改变当前路径:
复制目录文件:
此时bb目录以及它下面的目录cc,一并拷贝到aa目录下面了:
显示当前目录:
显示当前目录下的所有文件目录:
改变目录名:
改变目录名以后可以看到磁盘中aa已经变成了bc:
改变目录权限:
改变目录拥有者:
改变目录所属组:
查看文件类别:
新建文件
新建文件以后磁盘中已经有这两个文件:
删除文件
执行删除操作以后磁盘中文件已经删除:
写文件
拷贝文件
查看文件
建立文件联接
可以看到此时存在一个ce文件与aa虽然文件名不同,但是指向的是同一个I结点,相当于一个文件有两个名称。
修改文件权限、文件拥有者、文件所属组与前面的目录操作是相同的,这里不再重复演示。
六、重要函数及其实现方法
boolhavesame(char*dirname,INodeinode,int&
i,int&
index2)函数主要用于判断文件在当前路径下是否存在,输入文件名,当前路径目录文件的节点号inode,就可以通过inode节点中的addr定位到该目录文件,然后通过一个个查找,与dirname对比,找到相等的,就说明该目录文件中有该文件,可以对它进行操作。
该函数在整个程序的功能实现中都会用到,因为每进行一个文件操作,首先要判断它是否存在,只有存在该文件才可以对它进行一定的操作。
boolfind(char*string)函数同样是贯穿于整个程序,它的主要功能是找到string指明的路径,并且转换当前路径到该路径下,查找的过程主要是按照路径一个目录一个目录往下查找,每查找一个目录都是通过调用havesame函数实现的。
该函数在很多功能中都会用到,比如说将一个指定文件拷贝到指定路径下,就要通过该函数先确定该路径是否存在,并且转换到该路径下。
intballoc()函数用于申请新盘块,因为磁盘所有盘块都是通过成组链接法管理的,在该函数中每申请一个盘块的时候都会检查有没有到栈底,如果是栈底了,就必须先把栈底盘块里面存放的下一组盘块号调入栈中,然后把该盘块分配出去。
voidbfree(intindex)函数与申请盘块的函数相对应,它是用于指定盘块的回收的,同样的,为了实现成组链接法,当一个盘块回收时,必须先检查盘块号栈是否已满,如果已满,则先把栈里面的盘块号全部都写入要回收的盘块中,然后清空栈,把刚刚回收的盘块号写入栈底。
voidrmdir(char*dirname,intindex)该函数主要用于删除指定目录,删除目录时主要考虑的问题是该目录下面的子目录是不是也要删除了?
要怎样实现?
所以该函数中我要运用了递归的方法,删除该目录的时候先检查他下面是否有子目录,然后对每一个子目录执行该函数,如此循环,直到它为空目录了才将目录删除。
同样的在修改目录拥有者函数voidchown(char*name),目录所属组函数voidchgrp(char*name)中我也运用了同样的方法来实现该目录下面子目录文件,目录的拥有者、所属组修改。
voidwritefile(INodeinode,intin)该函数为文件写函数,该函数的实现也是比较复杂的,首先要调用读文件的函数voidreadfile(INodeinode)读入该文件原先的内容,将原先的内容与新写入的内容进行比较,如果原先内容多,那么先将多余的盘块回收了,然后将内容写入。
如果新写入的内容多,那么说明盘块不够,需要申请盘块,在申请盘块的过程中每申请一个盘块之前都要先判断原先内容有没有写到这一块,如果没有则进行申请,否则不用申请。
盘块申请完以后就可以将内容写入了。
其他比较简单的功能实现函数由于代码比较多,而且具体功能在模块详解以及系统流程设计的流程图中都有很详细的说明,这里就不再解释了,而且附上的源代码文件里面都已经写了很详细的注释,这里就不占篇幅了。
七、实验心得体会
本次实验中主要遇到的问题及解决方案:
◆写入文件的时候因为分配盘块用的是成组连接法,当读到一组里面最后一个盘块的时候需要从该盘块中读入下一组盘块号进入栈,每次运行到分配盘块的时候总是出错,分配前面几组都是正确的,但是到某一组就是读不进来下一组的盘块号,当时是设了断点一步步调试,还用写入的方法测试了下位置对不对,结果写入的位置是正确的,然后就郁闷了,不知道怎么回事,后来发现了一到读三位数的就不正确了,因为在盘块里面我初始化的时候,写入的都是每个盘块号只占了三个字节,所以三位数都是黏在一起的,中间没有空格,在读入的时候就不会读入一个个数,而是一长串数字,导致出错。
◆调试过程中最郁闷的事就是文件的打开关闭了。
刚开始没有注意这些问题,根本就没有注意文件的重复打开问题,导致在这个函数里面打开了disk.txt文件,还没有关闭,接下需要调用另外一个函数,文件又在另外一个函数里面被打开,结果在另一个文件里面就根本读不进文件里面的数据,因为这个毛病刚开始的时候出现了很多奇怪的现象,比如说在创建文件的函数里面,每创建一个函数申请一个盘块,就算申请了好几十个盘块都没有问题。
但是同样申请盘块在文件的写函数里就实现不了,因为在写函数里面我已经打开了disk.txt文件,而在盘块申请函数里面又打开了disk.txt文件。
本来是想每申请一个盘块,就先把内容写进去,实现边申请边写,结果申请到下一组的盘块就会出错,因为下一组的盘块根本没有读进栈。
◆技术性的问题也有,就是刚开始很多地方都是打算用string类型的数来传递值的,结果cout还有很多string类型自带的函数根本就不支持。
查看了头文件确实已经包括了<
string.h>
,后来终于还是XX了这个问题,然后发现XX上的解答也是要求要包含string
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 模拟 unix 文件系统 实验 报告 要点