操作系统课程设计-模拟文件系统班级:计算机044姓名:夏鑫学号:2004121228一.实验目的用高级语言编写和调试一个简单的文件系统。模拟文件管理的工作过程。加深理解文件系统的内部功能和内部实现。二.基本要求在任意一个OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的模拟UNIX文件系统。可以实现下列几条命令DIR列文件目录CREATE创建文件MD创建目录DELF删除文件DELD删除目录CD改变当前目录SAVEF保存文件SAVED保存目录HELP获得命令的帮助EXIT退出系统三.设计思想说明1.设计环境课程设计的环境是windowsxpsp2操作系统。在windows系统中创建一个较大容量的文件,作为所设计文件系统的假想的“文件卷”,从而编写各程序模块。2.开发环境课程设计所使用的开发环境是VC++6.03.基本思想以1M的存储器空间作为文件空间,空间“分块”。超级块,在最前面,共占3.2k个字节。其中0.2K个字节存放目录节点的位示图,1K个字节存放文件节点的位示图,2k字节存放盘块节点的位示图。用位状态='0'表示空闲,状态='1'表示已分配。后半部用于存放目录接点和文件接点。超级块不参与文件空间的动态分配。其他块用于存贮目录接点和文件接点的信息。四.需求分析该模拟文件系统包括目录文件(简称目录)、普通文件(简称文件),并实现下面一些基本功能:1.改变目录:CD〈目录名〉,工作目录转到指定的目录下。2.创建文件:CREATE〈文件名〉,创建一个指定名字的新文件,即在目录中增加一项,不考虑文件的内容。3.删除文件:DELF〈文件名〉,删除指定的文件。4.显示目录:DIR[〈目录名〉],显示目录下全部文件和第一级子目录,如果没有指定路径名,则显示当前目录下的内容。5.创建目录:MD〈目录名〉,再指定路径下创建指定的目录,或者在没有指定路径时,在当前目录下创建子目录。6.删除目录:DELD〈目录名〉,删除指定的目录。7.保存文件SAVEF〈目录名〉保存指定文件8.保存目录SAVED〈文件名〉,保存指定目录9.获得命令帮助HELP10.退出文件系统EXIT要考虑的特殊情况:1.各个命令对全路径和相对路径的支持1.目录不存在时,给出错误信息2.不能用cd进入文件3.相对路径的解析4.路径中的空格剔除2.新建目录或文件时的问题1重名问题;2目录或文件的名字长度限制;3目录或文件的名字中包含不合法字符(注意空格)3.删除目录或文件时的问题1删除不存在的文件或目录,给出错误提示2删除目录时目录不为空;如果该目录为空,则可删除,否则给出是否做删除,删除操作将该目录下的全部文件和子目录都删除3进入到某个目录下,却要删除本目录或者上级目录4.保存目录和文件时的问题1保存不存在的文件和目录,给出错误的提示2保存目录时,应当保存其下的的子目录和文件五.系统设计1.流程图2.数据结构1目录文件结点信息存储结构:structdir_node//目录节点{SYSTEMTIMEctime;//创建时间chardir_name[32];//目录名intchild_dir[8];//子目录索引intdir_count;//当前子目录数intchild_file[16];//子文件索引intfile_count;//当前子文件数intparent;//父目录索引}2文件目录存储位置存储结构:structfile_node//文件节点{SYSTEMTIMEctime;//创建时间charfile_name[32];//文件名intblock[4];//该文件占有的磁盘块索引打开文件系统open_file_system();接收命令并处理命令输入不是exit的命令当没有用户使用时,输入命令为exit关闭文件系统intblock_count;//该文件当前占有的磁盘块数intfile_length;//文件长度intparent;//父目录索引};3文件、目录、盘块的占用的标志位intdir_flag[DIR_NUM];//各目录节点占用标志,0表示空闲,1表示被占用intfile_flag[FILE_NUM];//各文件节点的占用标志intblock_flag[BLOCK_NUM];//磁盘块的占用标志4常驻内存的标志文件(目录)修改的标志位和标志文件(目录)修改标志位的标志位intdir_change_flag[DIR_NUM];//用于标志目录节点的修改intfile_change_flag[FILE_NUM];//用于标志文件节点的修改intdirflag_flag[DIR_NUM];//用于标志dir_flag[DIR_NUM]的修改intfileflag_flag[FILE_NUM];//用于标志file_flag[FILE_NUM]的修改intblockflag_flag[BLOCK_NUM];//用于标志block_flag[BLOCK_NUM]的修改5记录当前路径和当前目录的全局变量intcurr;//当前目录索引dir_node*curr_dir;//当前目录节点指针charcurr_path[512];//当前路径3.主要模块说明1创建文件intget_file(intparent,char*file_name)//创建文件节点,成功则返回文件的索引号,失败返回-1{intindex;if(search(parent,file_name,1,index)!=-1)//搜索在父目录下是否有同名文件存在,有则创建失败{printf(Filenamerepeated!\n);return-1;}for(inti=0;iFILE_NUM;i++)//搜索空闲的文件节点if(file_flag[i]==0){strcpy(file[i].file_name,file_name);file[i].block_count=0;if(get_block(i)==-1)//给新创建的文件申请磁盘块,如果失败,创建文件将失败{printf(Diskvolumnerror!\n);return-1;}file_flag[i]=1;fileflag_flag[i]++;//登记并给文件节点初始化file_change_flag[i]++;file[i].file_length=0;file[i].parent=parent;GetLocalTime(&file[i].ctime);//获得当前时间returni;}return-1;}intcreate_file(intparent,char*file_name)//在指定的目录下创建文件,如果创建成功则返回{//文件的索引号,否则返回-1if(dir[parent].file_count==16)//如果父目录已满,则创建失败{printf(Parentdirectoryisfull!\n);return-1;}intpos=get_file(parent,file_name);//开始创建文件if(pos==-1){printf(Createfileerror!\n);return-1;}dir_node*p=&dir[parent];//修改父目录的控制信息inttop=p-file_count;p-child_file[top]=pos;p-file_count++;dir_change_flag[parent]++;returnpos;}intcreate(char*name)//创建文件的主调函数,前提是已经取得要创建文件的索引{//成功返回文件的索引号,否则返回-1intparent,p=0;parent=get_parent(name,p);if(parent==-1)//找不到父目录,输入错误,创建失败{printf(Pathnameerror!\n);return-1;}returncreate_file(parent,name+p);//开始创建文件}2创建目录intcreate_dir(intparent,char*dir_name)//在指定的目录下创建目录,如果成功则返回目录{//的索引号,否则返回-1if(dir[parent].dir_count==8)//如果父目录已满,则创建失败{printf(Parentdirectoryisfull!\n);return-1;}intpos=get_dir(parent,dir_name);//开始创建目录if(pos==-1){printf(Createdirectoryerror!\n);return-1;}dir_node*p=&dir[parent];//修改父目录的控制信息inttop=p-dir_count;p-child_dir[top]=pos;p-dir_count++;dir_change_flag[parent]++;returnpos;}intmd(char*name)//创建目录的主调函数,它的参数只有用户输入{//如果创建成功,则返回目录的索引号,否则intparent,p=0;//返回-1parent=get_parent(name,p);if(parent==-1)//父目录找不到,输入有误,创建失败{printf(Pathnameerror!\n);return-1;}returncreate_dir(parent,name+p);//开始创建目录}3删除文件voiddel_file(intpos)//删除文件,调用该函数的前提是已经取得要删除文件的索引号{return_block(pos);//释放磁盘块file_flag[pos]=0;fileflag_flag[pos]++;file_change_flag[pos]=0;}intdel_file(intparent,char*file_name)//在指定的目录下删除文件,删除成功则返回文件的{//索引号,否则返回-1intdel_pos,index;if((del_pos=search(parent,file_name,1,index))==-1)//搜索该文件是否存在,不存在则删除失败{printf(Thefiletodeletenotexist!\n);return-1;}del_file(del_pos);//开始删除文件dir_node*p=&dir[parent];//修改父目录的控制信息if(p-file_count=2){inttop=p-file_count-1;p-child_file[index]=p-child_file[top];}p-file_count--;dir_change_flag[parent]++;returndel_pos;}intdelfile(char*name)//删除文件的主调函数,前提是知道了删除文件的名字{intparent,p=0;parent=get_parent(name,p);if(parent==-1){printf(Pathnameerror!\n);return-1;}returndel_file(parent,name+p);}4删除目录voiddel_dir(intpos)//删除指定的目录节点,该目录已经为空{dir_flag[pos]=0;dirflag_flag[pos]++;dir_change_flag[pos]=0;}voiddel(intpos)//删除一个指定目录及它下面的所有文件及所有目录{for(inti=0;idir[pos].file_count;i++)//删除当前目录下的所有文件del_file(dir[pos].child_file[i]);for(i=0;idir[pos].dir_count;i++)//删除子目录del(dir[pos].child_dir[i]);del_dir(pos);//删除当前目录}