操作系统课程设计说明书.docx
《操作系统课程设计说明书.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计说明书.docx(17页珍藏版)》请在冰豆网上搜索。
操作系统课程设计说明书
中北大学
操作系统课程设计
说明书
学院、系:
软件学院
专业:
软件工程
学生姓名:
学号:
设计题目:
模拟文件系统的设计与实现
起迄日期:
2016年12月21日-2017年1月4日
指导教师:
2016年12月20日
1、需求分析
1.1课程设计题目和目的
通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识,加深对教材中的重要算法的理解。
同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提
高综合运用各专业课知识的力。
1.2课程设计要求
通过课程设计,要求学生主要掌握以下内容:
a.文件的物理结构可以选用顺序分配,链表分配或索引分配。
b.建立文件:
从命令中得到文件名,得到该文件的文件长度,建立文件修改目录表。
c.删除文件:
回收文件占用的空间,修改目录表
d.读文件:
read[文件名][显示开始字节][显示的字节数],直接显示所需要的字节数。
e.写文件:
write[文件名][插入的位置][插入的内容]
f.查询属性:
显示文件属性,文件名,类型,长度,时间等。
1.3程序设计思想
此课程设计把TXT文件作为研究对象来模拟操作系统的文件系统的文件系统工作过程。
所以用一个字符串数组来模拟磁盘空间,顾名思义,模拟磁盘提供字符的存储服务。
磁盘空间分配表,采用链表结构,每个节点保存模拟磁盘的一个逻辑块的信息,包括块的最大长度,文件占用长度,占用标志。
如果占用标志为0,即该空间可分配给文件。
初始化磁盘空间时,从头开始遍历,检查占用位,如果该块位可分配,则检查块大小,若块长度大于或者等于申请空间的大小,则把块的前一部分(等于申请大小)分配给文件,并置标志位为占用。
剩下的大小做来一个新块,做来一个新的节点插入到原节点的后边,标志位为可用。
这样就实现了模拟磁盘的线性分配。
文件表,由于模拟文件系统的文件数量不多,故文件表采用线性表来存储。
线性表每个节点存储一个文件的信息。
打开文件表,采用数组形式存储打开的文件,数组每个元素保存一个打开文件的信息。
文件信息和文件表中的文件信息类似。
构造这些实体的关系图,数据流图。
程序流程图来进行具体的设计。
1.4实验环境
eclipse+jdk1.6.0_10
二、总体设计
2.1系统流程
开始
输入用户名
Y
输入的用户名为空
N
用户登录成功,创建用户根目录
用户进行各项操作,包括目录的创建粘贴和删除以及文件的相应操作,等等
Y
用户是否进行注销并切换到其他用户文件夹
N
用户退出
结束
图2.1.1
2.2文件结构
采用类似于树状的结构
。
。
。
。
。
。
。
用户二(以
用户名命名)
用户一(以用户名命名)
File111
Dir1
Dir2
Dir3
File2
Dir4
Dir5
File3
...............
Dir7
Dir6
图2.2.1
2.3实现操作
-------------------------以下为显示和跳转操作------------------------------
ls显示文件目录cd[dirname]:
跳转到指定目录cd..跳转到上层目录
---------------------------以下为目录操作--------------------------------
mkdir[dirname]:
创建目录ptdir[dirname]:
粘贴目录cpdir[dirname]:
拷贝目录
rnmdir[dirname]:
重命名目录rmdir[dirname]:
删除目录
---------------------------以下为文件操作--------------------------------
vim[filename]:
创建文件ptfile[filename]:
粘贴文件cpfile[filename]:
拷贝文件
rnmfile[filename]:
重命名文件rmfile[filename]:
删除文件vi[filename]:
显示文件内容
---------------------------以下为退出该系统操作----------------------------
exit
---------------------------以下为用户切换操作------------------------------
logout注销login[username]以该用户的身份登录add[username]添加新的用户并登录
---------------------------------------------------------------------
2.4数据结构
Src文件结构
用户类数据结构AllUser.java:
维护着一个包含所有用户的Map,单例模式,用户唯一。
文件类数据结构:
MyFile.java
磁盘块类数据结构:
MyDiskBlock.java
磁盘类数据结构:
MyDisk.java
目录类数据结构:
MyDir.java
2.5模块详解(流程图)
2.5.1.文件创建
开始创建文件
输入文件名称
Y
文件名称是否为空
N
创建文件失败
是否存在同名文件
N
成功创建文件
结束
图2.5.1
2.5.2文件编辑
开始编辑文件
输入文件名称
该文件是否存在
Y
进行编辑,点击回车保存内容
N
为其分配磁盘空间,循环更新父节点大小
编辑成功
结束
图2.5.2
2.5.3显示文件内容
开始
输入文件名称
该文件是否存在
ND
Y
显示文件内容失败
成功显示该文件内容
结束
D
图2.5.3
2.5.4文件删除
开始删除文件
输入文件名称
N
该文件是否存在
Y
删除失败
删除成功
循环更新父节点大小
结束
图2.5.4
2.5.5文件重命名
开始
输入文件名称
N
该文件是否存在
Y
Y
输入新文件名
重命名失败
是否存在同名文件
A
Y
Y
N
新文件名是否
为空
A
N
文件重命名成功
结束
图2.5.5
三、详细设计
1.进入模拟文件系统
图3.1.1
2.创建用户
输入用户名之后点击回车,即可成功创建用户根文件夹,此文件夹名称即为用户输入的用户名输入help即可查看相关帮助信息
图3.2.1
3.清屏
如果感觉屏幕输入信息较为繁杂,影响后续输入,可以输入cls进行清屏(注:
此处的清屏为假清屏,实际上是在控制台打印了30个空的换行,因为未能找到jdk中可以进行控制台清屏的方法)
图3.3.1
4.显示文件
输入visun即可把文件显示出来
代码实现:
elseif(s.startsWith("vi")&&s.length()>3){//显示文件内容,1
Stringfilename=s.substring(3,s.length());
MyFilea=nowdir.getFile(filename);
if(a!
=null){
ArrayListlist=a.getBlocklist();
StringBufferall=newStringBuffer();
for(MyDiskBlockone:
list){
all.append(one.getContent());
}
System.out.println(all);
}else
System.out.println("文件名称输入有误");
图3.4.1
5.复制和粘贴文件
图示如下,在根目录下创建了两个目录ln和linan,同时在ln目录中创建了一个名为sun的文件,在文件中输入了“first”的内容。
之后输入cpdirln将ln目录复制到剪切板中,在进入linan目录之后,输入ptdir指令将剪切板中的ln目录粘贴到linan目录中,可以看到目录的大小也随之更新,为确保该目录已经成功复制而不是简单的引用(包括其下的所有文件),以下进行验证进入linan/ln目录,可以看到sun文件,同时打开该文件进行编辑,输入“我是小太阳”等字样,保存退出,再进入根目录下的ln,显示其中的sun文件中的内容,发现依然是“first”而没有被修改为“我是小太阳”说明目录确实复制成功而非简单的引用
代码实现:
复制:
elseif(s.startsWith("cpfile")&&s.length()>7){//--->文件复制,1
Stringreal=s.substring(7,s.length());
MyFilea=nowdir.getFile(real);
if(a!
=null){
filesave=newMyFile();
filesave=a;
System.out.println("复制文件到剪切板成功");
}else
System.out.println("对不起,文件名输入有误");
粘贴:
elseif(s.equals("ptfile")){//--->文件粘贴,1
if(filesave!
=null){
ArrayListfileblocklist=filesave.getBlocklist();
if(nowdir.canPasteFile(filesave)){//判断目录下是否有同名文件
StringBufferrealcontent=newStringBuffer();
for(MyDiskBlockone:
fileblocklist){
realcontent.append(one.getContent());//先将文件中的StringBuffer全部拷贝出来
}
intpoint=0;
ArrayListnewFileBlocklist=newArrayList();//创建新的磁盘块列表用来存放这个StringBuffer
intblocksize=MyDiskBlock.getSize();
intsizecount=0;
ArrayListthenw=newArrayList();
if(realcontent.length()>blocksize){
for(inti=0;iStringBufferop=newStringBuffer(realcontent.substring(i,i+blocksize));
MyDiskBlocknewblock=newMyDiskBlock(op);
MyDisk.getInstance().addUsed(newblock);//
thenw.add(newblock.getId());
newFileBlocklist.add(newblock);
point=i;
sizecount++;
}
StringBufferrest=newStringBuffer(
realcontent.substring(point+blocksize,
realcontent.length()));
sizecount++;
MyDiskBlockano=newMyDiskBlock(rest);
MyDisk.getInstance().addUsed(ano);//修改后的内容保存到磁盘,一定要先保存到磁盘,在分配好磁盘号之后,再保存到文件
thenw.add(ano.getId());
newFileBlocklist.add(ano);//保存到文件
}else{
StringBuffershortone=newStringBuffer(
realcontent.substring(0,
realcontent.length()));
MyDiskBlockone=newMyDiskBlock(shortone);
sizecount++;
MyDisk.getInstance().addUsed(one);
thenw.add(one.getId());
newFileBlocklist.add(one);
}
MyDirsave2=newMyDir();
save2=nowdir;
while(nowdir.getFatherDir()!
=null){
nowdir.addnew(thenw);
nowdir.updateSize();
nowdir=nowdir.getFatherDir();
}
nowdir=save2;
MyFileanoth=newMyFile(filesave.getName());anoth.setBlocklist(newFileBlocklist);
anoth.setNewsize(filesave.getNewsize());
anoth.setOldsize(filesave.getOldsize());
nowdir.addFile(anoth);
}else
System.out.println("该目录下已经有同名文件,不能粘贴");
}
else
System.out.println("剪切板中没有文件");
}
图3.5.1
四、心得体会
经过俩周的课程设计,使我对操作系统有了更深的了解,进一步掌握了对操作系统的运用。
文件系统的编写过程中遇到了或大或小的问题,尤其在文件复制的操作中因为对剪切板中对象的误操作导致出现了非常奇怪的问题,几近奔溃,最终debug用时两个小时最终找到了问题的根源。
文件系统最终能够顺利完成离不开debug时的细心和耐心。
同时在代码的编写过程中,使用了单例和原型这两种设计模式,对设计模式的理解更近了一步。
当然,此文件系统也存在不足之处,如因为各个用户之间的目录文件相互独立,使用户的文件无法实现共享,对共享的文件在磁盘上磁盘块的分配也是需要考虑的问题;缺少超级管理员,缺乏对不同用户目录的直接管理等等。
团队合作是一种很必要的能力,每个人的能力都是有限的,没有人能只凭借自己自己一个人的能力就把一件事情做好,只有通过团队中每个成员的努力,发挥自己的长处,取长补短,最后才能将其做到最好。
在这次课程设计中,我们彼此之间在设计中产生了一点摩擦,但是通过大家的讨论协商都达到了一个共识,最后在大家共同努力完成了这次设计实验体会到了只有平时多练习,多看程序才能自己编写程序,同时应该自己多多调试程序,因为调试程序可以使我们了解我们在编程中的错误。
总而言之,本次大型试验增强了我们调错和分析问题的能力,收益良多。
当然,以后还需更加努力。