1、评定等级操作系统课程设计文件系统管理学院计算机学院专业计算机科学与技术班级姓名学号2013年1月8日广东工业大学计算机学院制文件系统管理一、实验目的模拟文件系统的实现的基本功能,了解文件系统的基本结构和文件系统的管理方法看,加深了解文件系统的内部功能的实现。通过高级语言编写和实现一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作系统命令的实质内容和执行过程有比较深入的了解。二、实验内容和要求编程模拟一个简单的文件系统,实现文件系统的管理和控制功能。在用户程序中通过使用文件系统提供的create,open,read,write,close,delete等文件命令,对文件进行操作。以下
2、报告主要包括:1.可行性分析2。需求分析3。概要设计4。详细设计5。测试6.总结三、可行性分析1、技术可行性对于图形编程还不了解,但是经过本学期的三次实验的练习,可以设计好命令操作界面.利用大二期间学习的数据结构可以模拟出此课程设计的要求。2、经济可行性课程设计作为本课程的练习及进一步加深理解.与经济无关,可以不考虑。(零花费,零收益)3。法律可行性自己编写的程序,仅为练习,不作其他用途,与外界没什么联系,可行。四、需求分析编写程序实现文件系统,主要有以下几点要求:1、实现无穷级目录管理及文件管理基本操作2、实现共享“别名”3、加快了文件检索五、概要设计为了克服单级目录所存在的缺点,可以为每一
3、位用户建立一个单独的用户文件目录UFD(User File Directory).这些文件目录可以具有相似的结构,它由用户所有文件的文件控制块组成。此外,在系统中再建立一个主文件目录MFD (Master File Directory);在主文件目录中,每个用户目录文件都占有一个目录项,其目录项中包括用户名和指向该用户目录的指针。本设计主要实现下面几个数据结构:M D F用户名文件目录指针用户名文件目录指针U F D文件名保护码文件长度文件名A F D打开文件名打开保护码读写指针总体的流程图如下:六、详细设计主要数据结构:1。MFD(Master File Directory),主要用以存放用
4、户,可以增加存放密码的字符数组,本设计没有保密安全方面的忧虑,为了使用时操作更简单省去密码.所以,MFD结构仅包括用户名和指向子目录的一个指针,以及指向下一用户的连接点,为线性结构。struct MFD char name20; /用户名 UFD *bst_pointer; /文件目录指针 MFD link;2. UFD(User File Directory),用于存放文件的数据结构.由于本设计为了加快检索速度,使用了二叉排序树的结构,所以UFD结构中相应加入了用于树结构的parent,leftchild,和rightchild记录链接情况.当本文件为普通文件时,为下级记录申请AFD(fil
5、e),folder为空.同样,当本文件为文件夹时,为它申请相应的空间,AFD为空.以此来达到无穷级别目录的存储.struct UFD UFD parent; UFD *leftchild; UFD *rightchild; UFD folder; /作为文件夹时指向下一层,文件时为空 UFD pre_folder; /指向上一层目录(文件夹时用到) AFD *file; /作文文件时文件的具体内容 char name30; /文件(夹)名字 int length; /作为文件时文件的长度,默认为0 char rw; /读写标志r or w char share; /共享标志y or n cha
6、r file_folder; /指示此文件是文件或文件夹,f为文件,o为文件夹;3.AFD,存放文件的内容的结构,比较简单,文件内容用一个字符数组存储,为顺序结构,最多可存放99个字符struct AFD char afd_file100; int read; /读指针 int write; /写指针;4.RECstruct REC /UFD的线性链,用于记录共享文件和已打开文件 UFD file; REC link;;关键函数说明:void Log_in(); /登陆void Init_user(); /创建用户void Check_user(); /查看用户以上三个函数为开始时管理用户创建
7、和登陆的函数。开始时没有用户,需要创建后才可登陆。创建用户即自动分配一个存放用户文件的UFD,此时的UFD为空,需要后续的创建文件以及文件夹的分配.UFD *operations(UFD fileBST); /文件夹的操作调用用户登陆后即开始对该用户文件UFD的操作,同时,若在文件夹中创建一个文件夹,它同样可以分配得到一个UFD,对用户文件的操作可以重复调用,以此来达到无穷级目录的操作.在里层文件的操作和外层的是一样的,但若要退回外层文件夹就需要逐层返回,不能立即跳到某一层某地址。操作完毕后返回改变后的文件存储状态。void fcreate(UFD *fileBST); /对文件夹的六个基本操
8、作UFD *fdelete(UFD fileBST);void fopen(UFD fileBST);void fclose(UFD fileBST);void fread_write(UFD *fileBST,char f); /读写操作。按选择f=5为读6为写以上五个函数为对文件的六个基本操作,其中读文件和写文件部分代码相同,所以由一个函数完成。在create五个函数中,分别对文件夹fileBST做了相应的处理,由于删除文件的函数可能会删除到头结点,所以需要一个返回值。void insertBST(UFD fileBST,UFD newBST); /在fileBST中插入新的结点newBS
9、TUFD searchBST(UFD fileBST,char name); /在fileBST树中查找名字为name的结 /点并返回该结点,文件不存在则返回空void BSTtraverse(UFD *fileBST); /遍历二叉树UFD *deleteBST(UFD fileBST,char name30); /删除name结点,返回删除后的结点由于该设计的存储结构用到了二叉排序树,所以把相关的操作写成函数,供基本操作的函数调用.insert函数在fileBST中插入新的结点newBST;search函数在fileBST树中查找名字为name的结点并返回该结点,文件不存在则返回空;还有t
10、raverse和delete函数对二叉排序树做了基本的操作。void print_path(UFD fileBST); /输出当前路径void print_open_file(); /输出已打开的文件为了在文件系统中使用户看出路径及一些相关的状态,设置了输出文件路径的函数,路径由每个文件的结构体中pre_folder记录上一层的文件夹名字,这样逐层输出即可达到目的。每执行一次操作就输出一次已打开的文件的具体情况,打开的文件应及时关闭,否则删除时会有删除失败提示。UFD *check_share(char name30); /在共享链中检查是否有name文件,有则/返回该UFD,没则NULLvo
11、id del_in_share(UFD *node); /在共享链中删除node结点以上两个函数为对共享文件的处理函数,当打开或读写文件时在本层文件中未找到相应的文件时,就用check_share函数在共享文件中查找,如果存在就返回该文件的UFD,不存在就返回NULL,而del_in_share函数是伴随着删除文件的函数出现的,目的是为了删除文件以后不会在共享链中再存在。具体代码如下:filesysterm。hstruct AFD char afd_file100; int read; /读指针 int write; /写指针;struct UFD UFD *parent; UFD leftc
12、hild; UFD rightchild; UFD *folder; /作为文件夹时指向下一层,文件时为空UFD *pre_folder; /指向上一层目录(文件夹时用到) AFD file; /作文文件时文件的具体内容 char name30; /文件(夹)名字 int length; /作为文件时文件的长度,默认为0 char rw; /读写标志r or w char share; /共享标志y or n char file_folder; /指示此文件是文件或文件夹,f为文件,o为文件夹;struct MFD char name20; /用户名 UFD *bst_pointer; /文件
13、目录指针 MFD *link;;struct REC /UFD的线性链,用于记录共享文件和已打开文件 UFD file; REC link;;void Log_in(); /登陆void Init_user(); /创建用户void Check_user(); /查看用户UFD operations(UFD fileBST); /文件夹的操作调用,user不为空时为第一层void fcreate(UFD *fileBST); /对文件夹的六个基本操作UFD *fdelete(UFD fileBST);void fopen(UFD fileBST);void fclose(UFD fileBST
14、);void fread_write(UFD fileBST,char f); /代码有重复,合并读写操作。按选择s=5为读6为写void insertBST(UFD fileBST,UFD *newBST); /新文件插入到user文件树中UFD *searchBST(UFD *fileBST,char name); /在fileBST树中查找名字为name的结点并返回该结点 /文件不存在则返回空void BSTtraverse(UFD *fileBST); /遍历二叉树UFD deleteBST(UFD *fileBST,char name30); /删除成功返回1,失败返回0void p
15、rint_path(UFD fileBST); /输出当前路径void print_open_file(); /输出已打开的文件UFD *check_share(char name30); /在共享链中检查是否有name文件,有则返回UFD,没则NULLvoid del_in_share(UFD *node); /在共享链中删除node结点main.cppinclude iostreamincludeconio。hincludefilesystem.h”MFD *mfd_link=NULL; /用户链表MFD pre_user; /当前操作用户UFD *pre_opera_folder=NUL
16、L;/当前操作文件夹int folder_depth=0; /记录当前文件深度(用于辅助pre_folder的初始化)REC share_file=NULL;REC open_file=NULL;void print_path(UFD *fileBST) /输出路径 if(fileBSTpre_folder!=NULL) print_path(fileBSTpre_folder); printf(”/%s”,fileBSTpre_foldername); else printf(/%s,pre_username);void print_open_file() REC *temp; int i=
17、5; temp=open_file; while(temp!=NULL) printf(stdtt,temp-filename,tempfilelength); if(temp-file-rw=r)printf(只读t”); else printf(可读写t”); if(temp-file-share=y)printf(是t”); else printf(否t”); for(i=0;i5;i+) if(tempfilefileafd_filei!=0) printf(c”,tempfilefileafd_filei); else break; if(tempfilefile-afd_filei
18、!=0i=5) printf(。”); printf(”n”); temp=templink; void BSTtraverse(UFD *fileBST) /遍历二叉树(前序遍历) UFD *left,right; printf(”s”,fileBSTname); if(fileBSTfile_folder=o) /输出。以区分文件夹 printf(”。t”); else printf(”t”); if(fileBSTleftchild!=NULL) /递归 left=fileBSTleftchild; BSTtraverse(left); if(fileBSTrightchild!=NUL
19、L) right=fileBSTrightchild; BSTtraverse(right); UFD searchBST(UFD *fileBST,char name30)/在fileBST树中查找名字为name的结点并返回该结点 /文件不存在则返回空 int flag; flag=strcmp(fileBST-name,name); if(flag=0) return fileBST; /查找成功 else if(flag0) if(fileBST-leftchild=NULL) return NULL; /查找失败 else searchBST(fileBSTleftchild,name
20、); /递归调用 else if(fileBST-rightchild=NULL) return NULL; else searchBST(fileBSTrightchild,name); void insertBST(UFD *fileBST,UFD newBST) /将结点newBST插入原二叉树fileBST中 int flag; flag=strcmp(fileBST-name,newBST-name); if(flag0) if(fileBSTleftchild=NULL) /插入 fileBST-leftchild=newBST; newBST-parent=fileBST; el
21、se insertBST(fileBSTleftchild,newBST); /递归调用 else if(fileBSTrightchild=NULL) /插入 fileBSTrightchild=newBST; newBST-parent=fileBST; else insertBST(fileBST-rightchild,newBST); /递归调用 /flag=0 的情况已在创建时排除/UFD *deleteBST(UFD *fileBST,char name30)/删除名字问name的文件结点 UFD *parent_file=NULL,del_file=NULL; UFD move_
22、file=NULL,move_file_parent; del_file=searchBST(fileBST,name); if(del_file=NULL) printf(没有此文件,删除失败!n”);getch(); return fileBST; /查找失败 if(del_file-file_folder=ostrcmp(del_file-foldername,”NULL”)!=0) printf(”注意,本系统未能实现级联删除,请先逐个删除文件!); printf(”文件夹非空,删除失败!n”);getch(); return fileBST; if(del_fileshare=y)
23、/先在共享链中删除 del_in_share(del_file); parent_file=del_file-parent; if(del_fileleftchild=NULL&del_filerightchild=NULL) /被删除结点为子叶结点 if(del_file=fileBST) /只有一个结点 strcpy(fileBST-name,NULL); else if(parent_fileleftchild=del_file) parent_fileleftchild=NULL;free(del_file); elseparent_filerightchild=NULL;free(d
24、el_file); else if(del_file-leftchild=NULL|del_file-rightchild=NULL) /被删除结点没有做孩子或右孩子 if(del_fileleftchild=NULL) /没有左孩子 if(parent_file=NULL)/删除的为根结点fileBST=del_file-rightchild;del_filerightchildparent=NULL; else if(parent_fileleftchild=del_file) /右孩子接上 parent_file-leftchild=del_filerightchild; del_fil
25、e-rightchildparent=parent_file; else /右孩子接上 parent_filerightchild=del_file-rightchild; del_file-rightchildparent=parent_file; else /没有右孩子 if(parent_file=NULL)/删除的为根结点fileBST=del_file-leftchild;del_fileleftchildparent=NULL; else if(parent_fileleftchild=del_file) /左孩子接上 parent_fileleftchild=del_filele
26、ftchild; del_fileleftchild-parent=parent_file; else /左孩子接上 parent_file-rightchild=del_fileleftchild; del_fileleftchildparent=parent_file; free(del_file); else /左右孩子都有 move_file_parent=del_file-leftchild; move_file=move_file_parentrightchild; if(move_file=NULL) /被删除结点的左孩子没有右孩子 if(parent_file=NULL) /删
27、除的为根结点 fileBST=move_file_parent; fileBST-rightchild=del_filerightchild; fileBST-parent=NULL; else if(parent_file-leftchild=del_file) parent_file-leftchild=move_file_parent; else parent_filerightchild=move_file_parent; move_file_parentparent=parent_file; move_file_parentrightchild=del_filerightchild;
28、 else while(move_filerightchild!=NULL) /寻找右边最底下的结点 move_file=move_filerightchild; move_file_parent=move_file_parent-rightchild; move_file_parentrightchild=NULL; move_file-leftchild=del_file-leftchild; move_filerightchild=del_filerightchild; if(move_file-rightchild!=NULL) move_filerightchild-parent=m
29、ove_file; /右孩子的双亲也要改变 move_file-parent=del_fileparent; if(fileBST=del_file) /删除的为根结点 fileBST=move_file; free(del_file); printf(”成功删除文件%sn,name); getch(); return fileBST;void del_in_share(UFD node) REC first,second; first=share_file; second=share_file-link; if(second=NULL) share_file=NULL;free(first)
30、; else do if(secondfile=node) first-link=secondlink;free(second); else first=firstlink; second=secondlink; while(second!=NULL);void fcreate(UFD fileBST) /在fileBST的同一层创建文件 char s;char name30;int flag=0; UFD newfile,*temp=NULL; REC stemp;system(”cls”); printf(”-n”); printf(- 文 件 系 统/创 建 文 件-n”); print
31、f(”-nn”); do printf(” 1。 创建文件 n”); printf( 2. 创建文件夹 n); printf(” 3. 取消 n”); printf(”请选择:n); scanf(%c”,&s); fflush(stdin); if(s=3)return; if(s!=1s!=2) printf(”输入错误,请重新输入!n); while(s!=1&s!=2);if(strcmp(fileBSTname,NULL”)=0) /节点已有(未赋值)用于本层文件夹的第一个文件的特殊情况 newfile=fileBST;elsenewfile=(UFD)malloc(sizeof(UF
32、D)); /创建树节点newfileleftchild=NULL;newfilerightchild=NULL; printf(”请输入文件(夹)名:”); scanf(”%s”,name); fflush(stdin); /搜索二叉树,文件重名就创建失败 temp=searchBST(fileBST,name); if(temp!=NULL) printf(”已存在该文件(夹),创建失败!n”); strcpy(newfilename,”NULL); return; strcpy(newfilename,name);if(folder_depth=1) newfile-pre_folder=
33、NULL;elsenewfilepre_folder=pre_opera_folder;/指向正在操作文件夹 while(1) /读写否,共享否 printf(”只读r还是可读写w:); scanf(”c”,&(newfile-rw)); fflush(stdin); printf(”是否共享y/n:”); scanf(%c”,(newfileshare)); fflush(stdin); if((newfilerw=rnewfilerw=w)&(newfileshare=y|newfileshare=n)) break; printf(”输入有误,请重新输入!n”); /*以下为文件和文件夹初始化中不同的地方* if(s=1) newfilefile_folder=f; newfilefolder=NULL; newfilefile=(AFD*)malloc(sizeof(AFD); printf(请输入文件的内容(100):”); scanf(”%s”,newfilefile-afd_file); fflush(stdin); newfile-length=str