虚拟文件系统.docx
《虚拟文件系统.docx》由会员分享,可在线阅读,更多相关《虚拟文件系统.docx(43页珍藏版)》请在冰豆网上搜索。
虚拟文件系统
虚拟文件系统
学生课程设计报告
2014~2015学年第二学期
学院XXXXXXXXX
专业软件工程
学号
姓名
指导教师
起止周
周数
1
实习地点
课程设计目的:
1、理解文件系统功能
2、完成对文件、目录及磁盘空间的管理并提供操作命令
3、实现文件共享与保护
课程设计要求:
1、利用索引结点实现目录管理。
2、建立一个树形目录系统,目录文件及索引结点均用结构数组表示。
3、文件盘块采用FAT方式,空指针用-1表示,并设空闲盘块指针。
4、提供对文件、目录及磁盘空间的操作命令。
进度安排及主要内容:
第一周:
完成用户登录,目录管理和文件管理
第二周:
成绩:
指导教师(签字)
年月日
一、概述
1.1本文的目的
本文内容用于指导学生对课程设计报告的格式和内容安排进行控制。
学生在使用时,可直接用格式刷将本文对应部分的格式内容进行提取并加载到目标位置;对于封面、页眉等部分,请直接修改相关文字。
二、需求分析
本次要实现虚拟文件系统,主要功能有用户登录、子目录的创建、删除、子目录中项的显示;文件的创建、打开、删除、关闭、对文件进行读写等。
实现对目录和文件的基本操作和文件的共享与保护。
三、技术方案
本次课程设计用VS2013编写C++控制台程序模拟文件系统。
系统初始时需要登录,登录成功方能对文件进行操作。
本虚拟文件系统采用两级目录,第一级目录对应用户账号,第二级目录对应用户下的文件。
文件系统的数据结构包括主目录(虚拟C盘)、子目录及所含文件等。
三者都存放在磁盘中,方便进行操作。
文件可以在目录中进行记录,表明文件所在目录。
四、总体设计
4.1功能设计
1、首次运行系统需要先格式化磁盘空间,申请一个内存为1M的磁盘空间。
2、用户登录,用户需输入正确的用户名和密码方能进入本系统进行文件和目录的操作。
3、进入系统后可根据提示对文件和目录进行操作。
4.2虚拟文件系统算法流程图
算法流程图4-1
五、详细设计
5.1系统功能说明
1、创建子目录:
输入createdir目录名,即进行目录创建操作,若当前目录已满或文件名已经存在则创建失败,返回失败信息。
否则创建成功,并找到空闲磁盘块,将该磁盘块设为已分配,填写目录项。
2、删除子目录:
removedir目录名,检查当前目录项中有无该目录,判断要删除的目录有无子目录,如果有子目录将其释放,进行删除操作。
3、更改当前目录:
cd目录名,可以进入到子目录并回退上级目录。
4、显示目录中项:
showdir可以显示目录和文件,文件显示大小,目录显示[目录]。
5、文件操作:
创建文件、打开文件(创建时自动打开该文件),删除文件,关闭文件、读文件、写文件、
6、退出
5.2数据结构
structdirect
{
/**
*文件控制快信息
*/
structFCB
{
charname[9];//文件/目录名8位
charproperty;//属性1位目录0位普通文件
intsize;//文件/目录字节数、盘块数)
intfirstdisk;//文件/目录起始盘块号
intnext;//子目录起始盘块号
intsign;//1是根目录0不是根目录
}directitem[MSD+2];
};
/**
*size8
*/
structfatitem
{
intitem;//存放文件下一个磁盘的指针
charem_disk;//磁盘块是否空闲标志位0空闲
};
structopentable
{
structopenttableitem
{
charname[9];//文件名
intfirstdisk;//起始盘块号
intsize;//文件的大小
}openitem[MOFN];
intcur_size;//当前打文件的数目
};
structfatitem*fat;//FAT表
structdirect*root;//根目录
structdirect*cur_dir;//当前目录
structopentableu_opentable;//文件打开表
5.3方法函数
voidinitfile();
voidformat();
voidenter();
voidinit();
intcreate(char*name);
intopen(char*name);
intclose(char*name);
intwrite(intfd,char*buf,intlen);
intread(intfd,char*buf);
intdel(char*name);
intcreatedir(char*name);
intremovedir(char*name);
voidshowdir();
intcd(char*name);
voidprint();
voidshow();
voidlogin();
5.4全局变量
#defineMEM_D_SIZE1024*1024//总磁盘空间为M
#defineDISKSIZE1024//磁盘块的大小K
#defineDISK_NUM1024//磁盘块数目K
#defineFATSIZEDISK_NUM*sizeof(structfatitem)//FAT表大小
#defineROOT_DISK_NOFATSIZE/DISKSIZE+1//根目录起始盘块号
#defineROOT_DISK_SIZEsizeof(structdirect)//根目录大小
#defineDIR_MAXSIZE1024//路径最大长度为KB
#defineMSD6//最大子目录数
#defineMOFN4//最大文件深度为
#defineMAX_WRITE1024*128//最大写入文字长度KB
char*username=(char*)malloc(sizeof(char)*100);
char*password=(char*)malloc(sizeof(char)*100);
六、软件测试
6.1格式化磁盘空间测试
6.2用户登录测试
6.3创建子目录测试
6.4进入子目录测试
6.5创建文件测试
6.6写入文件测试
6.7读文件测试
6.8返回上级目录测试
6.9显示目录中项测试
6.10读写权限测试
七、总结
本次课程设计我初步完成了虚拟文件系统的目录管理和文件管理。
让我对于文件系统有了深层次的理解和掌握,通过自己编写程序逐步提高自己的编程能力,并从中体会到了很多乐趣和知识。
同时让我对C语言中的指针有了一个更深的了解。
由于以前对于C++知识没有掌握牢固,使我在编程中出现了很多错误。
费了很多时间,但是我通过不断学习也提高了很多,对一些细节的结构体等也有了一个更深的理解。
这次课程设计让我进行了以前课堂很少有的实践训练,虽然掌握的知识有限,但是这次经历让我提高了编程能力和编程思想,使我受益匪浅。
附录1
参考文献
[1]谭浩强,C++程序设计(第2版).清华大学出版社,2012.
[2]汤小丹、梁红兵、哲凤屏,计算机操作系统.西安电子科技大学出版社,2014.
[3]严蔚敏.数据结构.清华大学出版社.,2007
附录2
源码
//kcsj001.cpp:
Definestheentrypointfortheconsoleapplication.
//
#include"stdafx.h"
#include
#include
#include
#defineMEM_D_SIZE1024*1024//总磁盘空间为M
#defineDISKSIZE1024//磁盘块的大小K
#defineDISK_NUM1024//磁盘块数目K
#defineFATSIZEDISK_NUM*sizeof(structfatitem)//FAT表大小
#defineROOT_DISK_NOFATSIZE/DISKSIZE+1//根目录起始盘块号
#defineROOT_DISK_SIZEsizeof(structdirect)//根目录大小
#defineDIR_MAXSIZE1024//路径最大长度为KB
#defineMSD6//最大子目录数
#defineMOFN4//最大文件深度为
#defineMAX_WRITE1024*128//最大写入文字长度KB
char*username=(char*)malloc(sizeof(char)*100);
char*password=(char*)malloc(sizeof(char)*100);
structdirect
{
/**
*文件控制快信息
*/
structFCB
{
charname[9];//文件/目录名8位
charproperty;//属性1位目录0位普通文件
intsize;//文件/目录字节数、盘块数)
intfirstdisk;//文件/目录起始盘块号
intnext;//子目录起始盘块号
intsign;//1是根目录0不是根目录
}directitem[MSD+2];
};
/**
*size8
*/
structfatitem
{
intitem;//存放文件下一个磁盘的指针
charem_disk;//磁盘块是否空闲标志位0空闲
};
structopentable
{
structopenttableitem
{
charname[9];//文件名
intfirstdisk;//起始盘块号
intsize;//文件的大小
}openitem[MOFN];
intcur_size;//当前打文件的数目
};
structfatitem*fat;//FAT表
structdirect*root;//根目录
structdirect*cur_dir;//当前目录
structopentableu_opentable;//文件打开表
intfd=-1;//文件打开表的序号
char*bufferdir;//记录当前路径的名称
char*fdisk;//虚拟磁盘起始地址
voidinitfile();
voidformat();
voidenter();
voidhalt();
intcreate(char*name);
intopen(char*name);
intclose(char*name);
intwrite(intfd,char*buf,intlen);
intread(intfd,char*buf);
intdel(char*name);
intmkdir(char*name);
intrmdir(char*name);
voiddir();
intcd(char*name);
voidprint();
voidshow();
voidlogin();
main()
{
FILE*fp;
charch;
chara[100];
charcode[11][10];
charname[10];
inti,flag,r_size;
char*contect;
contect=(char*)malloc(MAX_WRITE*sizeof(char));
if((fp=fopen("disk.dat","rb"))==NULL)
{
printf("您还没有格式化,是否格式化?
(y/n)");
scanf("%c",&ch);
if(ch=='y')
{
initfile();
printf("格式化成功!
\n");
}
else
{
return0;
}
}
printf("您还未登录,请先登录!
\n");
GotoTest:
login();
if((strcmp(username,"readonly")!
=0||strcmp(password,"1234")!
=0)
&&(strcmp(username,"root")!
=0||strcmp(password,"root")!
=0)
&&(strcmp(username,"nopower")!
=0||strcmp(password,"1234")!
=0)){
printf("登录失败,请重新登录!
\n");
gotoGotoTest;
}
printf("登录成功!
\n");
enter();
print();
show();
strcpy(code[0],"exit");
strcpy(code[1],"create");
strcpy(code[2],"open");
strcpy(code[3],"close");
strcpy(code[4],"write");
strcpy(code[5],"read");
strcpy(code[6],"del");
strcpy(code[7],"createdir");
strcpy(code[8],"removedir");
strcpy(code[9],"showdir");
strcpy(code[10],"cd");
while
(1)
{
scanf("%s",a);
for(i=0;i<11;i++)
{
if(!
strcmp(code[i],a))
break;
}
switch(i)
{
case0:
//退出文件系统
free(contect);
halt();
return0;
case1:
//创建文件
scanf("%s",name);
flag=create(name);
if(flag==-1)
{
printf("Error:
\n长度太长!
\n");
}
elseif(flag==-2)
{
printf("Error:
\n子目录已满!
\n");
}
elseif(flag==-3)
{
printf("Error:
\n打开文件次数过多!
\n");
}
elseif(flag==-4)
{
printf("Error:
\n名字已经在子目录中!
\n");
}
elseif(flag==-5)
{
printf("Error:
\n磁盘空间已满!
\n");
}
else
{
printf("创建文件成功!
\n");
}
show();
break;
case2:
//打开文件
scanf("%s",name);
fd=open(name);
if(fd==-1)
{
printf("Error:
\n打开的文件不存在!
\n");
}
elseif(fd==-2)
{
printf("Error:
\n文件已经打开!
\n");
}
elseif(fd==-3)
{
printf("Error:
\n打开文件次数过多!
\n");
}
elseif(fd==-4)
{
printf("Error:
\n这是一个子目录,不能打开进行读写!
\n");
}
else
{
printf("打开成功!
\n");
}
show();
break;
case3:
//关闭文件
scanf("%s",name);
flag=close(name);
if(flag==-1)
{
printf("Error:
\n文件没有打开!
\n");
}
else
{
printf("关闭成功!
\n");
}
show();
break;
case4:
//写文件
if(fd==-1)
{
printf("Error:
\n文件没有打开!
\n");
}
else
{
if(strcmp(username,"readonly")!
=0&&strcmp(username,"nopower")!
=0){
printf("请输入文件内容:
");
scanf("%s",contect);
flag=write(fd,contect,strlen(contect));
if(flag==0)
{
printf("写入成功!
\n");
}
else
{
printf("Error:
\n磁盘大小没满!
\n");
}
}
else{
printf("您没有写入权限!
\n");
}
}
show();
break;
case5:
//读文件
if(fd==-1)
{
printf("Error:
\n文件没有打开!
\n");
}
else
{
if(strcmp(username,"nopower")!
=0){
flag=read(fd,contect);
if(flag==0)
{
for(i=0;i{
printf("%c",contect[i]);
}
printf("\t\n");
}
}
else{
printf("您没有读取权限!
\n");
}
}
show();
break;
case6:
//删除文件
scanf("%s",name);
flag=del(name);
if(flag==-1)
{
printf("Error:
\n文件不存在!
\n");
}
elseif(flag==-2)
{
printf("Error:
\n文件已经打开,请先关闭它!
\n");
}
elseif(flag==-3)
{
printf("Error:
\n删除的不是文件!
\n");
}
else
{
printf("删除成功!
\n");
}
show();
break;
case7:
//创建子目录
scanf("%s",name);
flag=mkdir(name);
if(flag==-1)
{
printf("Error:
\n名称长度太长!
\n");
}
elseif(flag==-2)
{
printf("Error:
\n子目录已满!
\n");
}
elseif(flag==-3)
{
printf("Error:
\n名称已在子目录中!
\n");
}
elseif(flag==-4)
{
printf("Error:
\n'..'或'.'不能作为子目录名称!
\n");
}
elseif(flag==-5)
{
printf("Error:
\n磁盘空间已满!
\n");
}
elseif(flag==0)
{
printf("创建子目录成功!
\n");
}
show();
break;
case8:
//删除子目录
scanf("%s",name);
flag=rmdir(name);
if(flag==-1)
{
printf("Error:
\n子目录不存在!
\n");
}
elseif(flag==-2)
{
printf("Error:
\n子目录中含有子目录,请删除子目录中的子目录!
\n");
}
elseif(flag==-3)
{
printf("Error:
\n删除的不是子目录!
\n");
}
elseif(flag==0)
{
printf("删除子目录成功!
\n");
}
show();
break;
case9:
//显示当前子目录
dir();
show();
break;
case10:
//更改当前目录
scanf("%s",name);
flag=cd(name);
if(flag==-1)
{
printf("Error:
\n路径不正确!
\n");
}
elseif(flag==-2)
{
printf("Error:
\n打开的不是子目