操作系统课程设计 文件系统管理Word格式.docx
《操作系统课程设计 文件系统管理Word格式.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计 文件系统管理Word格式.docx(32页珍藏版)》请在冰豆网上搜索。
1、实现无穷级目录管理及文件管理基本操作
2、实现共享“别名”
3、加快了文件检索
五、概要设计
为了克服单级目录所存在的缺点,可以为每一位用户建立一个单独的用户文件目录UFD(UserFileDirectory)。
这些文件目录可以具有相似的结构,它由用户所有文件的文件控制块组成。
此外,在系统中再建立一个主文件目录MFD(MasterFileDirectory);
在主文件目录中,每个用户目录文件都占有一个目录项,其目录项中包括用户名和指向该用户目录的指针。
本设计主要实现下面几个数据结构:
MDF
用户名
文件目录指针
UFD
文件名
保护码
文件长度
·
AFD
打开文件名
打开保护码
读写指针
总体的流程图如下:
六、详细设计
主要数据结构:
1.MFD(MasterFileDirectory),主要用以存放用户,可以增加存放密码的字符数组,本设计没有保密安全方面的忧虑,为了使用时操作更简单省去密码。
所以,MFD结构仅包括用户名和指向子目录的一个指针,以及指向下一用户的连接点,为线性结构。
structMFD
{
charname[20];
//用户名
UFD*bst_pointer;
//文件目录指针
MFD*link;
};
2.UFD(UserFileDirectory),用于存放文件的数据结构。
由于本设计为了加快检索速度,使用了二叉排序树的结构,所以UFD结构中相应加入了用于树结构的parent,leftchild,和rightchild记录链接情况。
当本文件为普通文件时,为下级记录申请AFD(file),folder为空。
同样,当本文件为文件夹时,为它申请相应的空间,AFD为空。
以此来达到无穷级别目录的存储。
structUFD
UFD*parent;
UFD*leftchild;
UFD*rightchild;
UFD*folder;
//作为文件夹时指向下一层,文件时为空
UFD*pre_folder;
//指向上一层目录(文件夹时用到)
AFD*file;
//作文文件时文件的具体内容
charname[30];
//文件(夹)名字
intlength;
//作为文件时文件的长度,默认为0
charrw;
//读写标志rorw
charshare;
//共享标志yorn
charfile_folder;
//指示此文件是文件或文件夹,f为文件,o为文件夹
3.AFD,存放文件的内容的结构,比较简单,文件内容用一个字符数组存储,为顺序结构,最多可存放99个字符
structAFD
charafd_file[100];
intread;
//读指针
intwrite;
//写指针
4.REC
structREC//UFD的线性链,用于记录共享文件和已打开文件
UFD*file;
REC*link;
关键函数说明:
voidLog_in();
//登陆
voidInit_user();
//创建用户
voidCheck_user();
//查看用户
以上三个函数为开始时管理用户创建和登陆的函数。
开始时没有用户,需要创建后才可登陆。
创建用户即自动分配一个存放用户文件的UFD,此时的UFD为空,需要后续的创建文件以及文件夹的分配。
UFD*operations(UFD*fileBST);
//文件夹的操作调用
用户登陆后即开始对该用户文件UFD的操作,同时,若在文件夹中创建一个文件夹,它同样可以分配得到一个UFD,对用户文件的操作可以重复调用,以此来达到无穷级目录的操作。
在里层文件的操作和外层的是一样的,但若要退回外层文件夹就需要逐层返回,不能立即跳到某一层某地址。
操作完毕后返回改变后的文件存储状态。
voidfcreate(UFD*fileBST);
//对文件夹的六个基本操作
UFD*fdelete(UFD*fileBST);
voidfopen(UFD*fileBST);
voidfclose(UFD*fileBST);
voidfread_write(UFD*fileBST,charf);
//读写操作。
按选择f=5为读6为写
以上五个函数为对文件的六个基本操作,其中读文件和写文件部分代码相同,所以由一个函数完成。
在create五个函数中,分别对文件夹fileBST做了相应的处理,由于删除文件的函数可能会删除到头结点,所以需要一个返回值。
voidinsertBST(UFD*fileBST,UFD*newBST);
//在fileBST中插入新的结点newBST
UFD*searchBST(UFD*fileBST,charname);
//在fileBST树中查找名字为name的结
//点并返回该结点,文件不存在则返回空
voidBSTtraverse(UFD*fileBST);
//遍历二叉树
UFD*deleteBST(UFD*fileBST,charname[30]);
//删除name结点,返回删除后的结点
由于该设计的存储结构用到了二叉排序树,所以把相关的操作写成函数,供基本操作的函数调用。
insert函数在fileBST中插入新的结点newBST;
search函数在fileBST树中查找名字为name的结点并返回该结点,文件不存在则返回空;
还有traverse和delete函数对二叉排序树做了基本的操作。
voidprint_path(UFD*fileBST);
//输出当前路径
voidprint_open_file();
//输出已打开的文件
为了在文件系统中使用户看出路径及一些相关的状态,设置了输出文件路径的函数,路径由每个文件的结构体中pre_folder记录上一层的文件夹名字,这样逐层输出即可达到目的。
每执行一次操作就输出一次已打开的文件的具体情况,打开的文件应及时关闭,否则删除时会有删除失败提示。
UFD*check_share(charname[30]);
//在共享链中检查是否有name文件,有则//返回该UFD,没则NULL
voiddel_in_share(UFD*node);
//在共享链中删除node结点
以上两个函数为对共享文件的处理函数,当打开或读写文件时在本层文件中未找到相应的文件时,就用check_share函数在共享文件中查找,如果存在就返回该文件的UFD,不存在就返回NULL,而del_in_share函数是伴随着删除文件的函数出现的,目的是为了删除文件以后不会在共享链中再存在。
具体代码如下:
filesysterm.h
//文件夹的操作调用,user不为空时为第一层
//代码有重复,合并读写操作。
按选择s=5为读6为写
//新文件插入到user文件树中
//在fileBST树中查找名字为name的结点并返回该结点
//文件不存在则返回空
//删除成功返回1,失败返回0
//在共享链中检查是否有name文件,有则返回UFD,没则NULL
main.cpp
#include<
iostream>
#include<
conio.h>
#include"
filesystem.h"
MFD*mfd_link=NULL;
//用户链表
MFD*pre_user;
//当前操作用户
UFD*pre_opera_folder=NULL;
//当前操作文件夹
intfolder_depth=0;
//记录当前文件深度(用于辅助pre_folder的初始化)
REC*share_file=NULL;
REC*open_file=NULL;
voidprint_path(UFD*fileBST)//输出路径
if(fileBST->
pre_folder!
=NULL)
{print_path(fileBST->
pre_folder);
printf("
/%s"
fileBST->
pre_folder->
name);
}
else
pre_user->
}
voidprint_open_file()
REC*temp;
inti=5;
temp=open_file;
while(temp!
{
%s\t%d\t\t"
temp->
file->
name,temp->
length);
if(temp->
rw=='
r'
)printf("
只读\t"
);
elseprintf("
可读写\t"
share=='
y'
是\t"
否\t"
for(i=0;
i<
5;
i++)
afd_file[i]!
='
\0'
)
%c"
afd_file[i]);
elsebreak;
&
i==5)printf("
.."
\n"
temp=temp->
link;
voidBSTtraverse(UFD*fileBST)//遍历二叉树(前序遍历)
UFD*left,*right;
%s"
file_folder=='
o'
)//输出..以区分文件夹
..\t"
\t"
leftchild!
=NULL)//递归
left=fileBST->
leftchild;
BSTtraverse(left);
rightchild!
right=fileBST->
rightchild;
BSTtraverse(right);
UFD*searchBST(UFD*fileBST,charname[30])//在fileBST树中查找名字为name的结点并返回该结点
{//文件不存在则返回空
intflag;
flag=strcmp(fileBST->
name,name);
if(flag==0)
returnfileBST;
//查找成功
elseif(flag>
0)
leftchild==NULL)returnNULL;
//查找失败
searchBST(fileBST->
leftchild,name);
//递归调用
rightchild==NULL)returnNULL;
rightchild,name);
voidinsertBST(UFD*fileBST,UFD*newBST)//将结点newBST插入原二叉树fileBST中
name,newBST->
if(flag>
leftchild==NULL)//插入
fileBST->
leftchild=newBST;
newBST->
parent=fileBST;
insertBST(fileBST->
leftchild,newBST);
rightchild==NULL)//插入
rightchild=newBST;
rightchild,newBST);
/*flag=0的情况已在创建时排除*/
UFD*deleteBST(UFD*fileBST,charname[30])//删除名字问name的文件结点
UFD*parent_file=NULL,*del_file=NULL;
UFD*move_file=NULL,*move_file_parent;
del_file=searchBST(fileBST,name);
if(del_file==NULL)
没有此文件,删除失败!
getch();
if(del_file->
strcmp(del_file->
folder->
name,"
NULL"
)!
=0)
{printf("
注意,本系统未能实现级联删除,请先逐个删除文件!
"
文件夹非空,删除失败!
)//先在共享链中删除
del_in_share(del_file);
parent_file=del_file->
parent;
leftchild==NULL&
del_file->
rightchild==NULL)//被删除结点为子叶结点
if(del_file==fileBST)//只有一个结点
strcpy(fileBST->
elseif(parent_file->
leftchild==del_file)
{
parent_file->
leftchild=NULL;
free(del_file);
}
parent_file->
rightchild=NULL;
elseif(del_file->
leftchild==NULL||del_file->
rightchild==NULL)//被删除结点没有做孩子或右孩子
leftchild==NULL)//没有左孩子
if(parent_file==NULL)//删除的为根结点
{
fileBST=del_file->
del_file->
rightchild->
parent=NULL;
}
leftchild==del_file)//右孩子接上
leftchild=del_file->
del_file->
parent=parent_file;
else//右孩子接上
rightchild=del_file->
else//没有右孩子
leftchild->
leftchild==del_file)//左孩子接上
else//左孩子接上
free(del_file);
else//左右孩子都有
move_file_parent=del_file->
move_file=move_file_parent->
if(move_file==NULL)//被删除结点的左孩子没有右孩子
if(parent_file==NULL)//删除的为根结点
fileBST=move_file_parent;
leftchild=move_file_parent;
rightchild=move_file_parent;
move_file_parent->
while(move_file->
=NULL)//寻找右边最底下的结点
move_file=move_file->
move_file_parent=move_file_parent->
move_file->
if(move_file->
parent=move_file;
//右孩子的双亲也要改变
parent=del_file->
if(fileBST==del_file)//删除的为根结点
fileBST=move_file;
f