操作系统课程设计报告简单文件系统的实现专业:班级:姓名:学号:老师:一、课程设计的目的1.通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部数据结构、功能以及实现过程的理解。二、课程设计要求1.在内存中开辟一个虚拟磁盘空间作为文件存储分区,在其上实现一个简单的基于多级目录的单用户单任务系统中的文件系统。在退出该文件系统的使用时,应将该虚拟文件系统以一个Windows文件的方式保存到磁盘上,以便下次可以再将它恢复到内存的虚拟磁盘空间中。2文件存储空间的分配可采用显式链接分配或其他的办法。3空闲磁盘空间的管理可选择位示图或其他的办法。如果采用位示图来管理文件存储空间,并采用显式链接分配方式,那么可以将位示图合并到FAT中。文件目录结构采用多级目录结构。为了简单起见,可以不使用索引结点,其中的每个目录项应包含文件名、物理地址、长度等信息,还可以通过目录项实现对文件的读和写的保护。要求提供以下有关的操作命令:my_format:对文件存储器进行格式化,即按照文件系统的结构对虚拟磁盘空间进行布局,并在其上创建根目录以及用于管理文件存储空间等的数据结构。my_mkdir:用于创建子目录。my_rmdir:用于删除子目录。my_ls:用于显示目录中的内容。my_cd:用于更改当前目录。my_create:用于创建文件。my_open:用于打开文件。my_close:用于关闭文件。my_write:用于写文件。my_read:用于读文件。my_rm:用于删除文件。my_exitsys:用于退出文件系统。三、程序的设计细想和框图1.打开文件函数fopen()(1)格式:FILE*fopen(constchar*filename,constchar*mode)(2)功能:按照指定打开方式打开指定文件。(3)输入参数说明:filename:待打开的文件名,如果不存在就创建该文件。mode:文件打开方式,常用的有:r:为读而打开文本文件(不存在则出错)。w:为写而打开文本文件(若不存在则创建该文件;反之,则从文件起始位置写,原内容将被覆盖)。a:为在文件末尾添加数据而打开文本文件。(若不存在则创建该文件;反之,在原文件末尾追加)。r+:为读和写而打开文本文件。(读时,从头开始;在写数据时,新数据只覆盖所占的空间,其后不变)。w+:首先建立一个新文件,进行写操作,随后可以从头开始读。(若文件存在,原内容将全部消失)。a+:功能与a相同;只是在文件末尾添加新的数据后,可以从头开始读。另外,上述模式字符串中都可以加一个“b”字符,如rb、wb、ab、rb+、wb+、ab+等组合,字符“b”表示fopen()函数打开的文件为二进制文件,而非纯文字文件。(4)输出:一个指向FILE类型的指针。2.关闭文件函数fclose()(1)格式:intfclose(FILE*stream);(2)功能:用来关闭先前fopen()打开的一个文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。(3)输入参数说明:stream:指向要关闭文件的指针,它是先前执行fopen()函数的返回值。(4)输出:若关闭文件成功则返回0;有错误发生时则返回EOF并把错误代码存到errno。3.读文件函数fread()(1)格式:size_tfread(void*buffer,size_tsize,size_tcount,FILE*stream);(2)功能:读二进制文件到内存。(3)输入参数说明:buffer:用于存放输入数据的缓冲区的首地址;stream:使用fopen()打开的文件的指针,用于指示要读取的文件;size:每个数据块的字节数;count:要读入的数据块的个数;size*count:表示要求读取的字节数。(4)输出:实际读取的数据块的个数。4.写文件函数fwrite()(1)格式:size_tfwite(constvoid*buffer,size_tsize,size_tcount,FILE*stream);(2)功能:将数据写到二进制文件中。(3)输入参数说明:buffer:用于存放输出数据的缓冲区的首地址;stream:使用fopen()打开的文件的指针,用于指示要写出的文件;size:每个数据块的字节数;count:要写出的数据块的个数;size*count:表示要求写出的字符数。(4)输出:实际写出的数据块的个数。5.判断文件结束函数feof()(1)格式:intfeof(FILE*stream)(2)功能:用来判断是否已读取到文件末尾。(3)输入参数说明:stream:使用fopen()打开的文件的指针,用于指示要判断的文件。(4)输出:如果已读到文件尾则返回非零值,其他情况返回0。6主要函数功能实现:intformat();//格式化磁盘intmkdir(char*sonfname);//创建子目录intrmdir(char*sonfname);//删除子目录intcreate(char*name);//创建文件intlistshow();//显示子文件信息intdelfile(char*name);//删除文件intchangePath(char*sonfname);//更改当前路径intwrite(char*name);//写入文件intexit();//退出系统intopen(char*file);//打开文件intclose(char*file);//关闭文件intread(char*file);//读取文件7主要的框架四、程序实现和程序调试遇到的问题的分析1对于DOS的文件操作使用不熟悉,经常输入错误命令2调试的时候跟踪变量的时候,难以锁定实际的变量是什么3对于文件的存储结构不熟悉,在构造FAT的时候不知如何解决,查阅了大量的资料和跟老师交流才慢慢开始理解4由于买的实验册对于文件的介绍过于简单,导致理解上出现很大的困难。五、结果分析和总结1基本上实现了DOS下简单文件系统的实现,通过学习基本掌握了文件系统的存储结构2当遇到困难的时候通过认真思考很查阅资料很大问题都是可以自己解决的。通过这次实验锻炼了自己的动手的能力和分析问题的能力3在构造函数的时候可以开阔思维同时加深自己对文件系统实现的理解4通过这样的实验开始对DOS的环境文件命令输入有了初步的理解5通过跟老师的讨论解决自己心中的疑惑六、程序#includestdio.h#includememory.h#includestring#includeiostreamusingnamespacestd;#defineGENERAL1//1代表普通文件2代表目录文件0表示空文件#defineDIRECTORY2#defineZero0structFCB{charfname[16];//文件名chartype;//0空文件1目录文件2空文件intsize;//文件大小intfatherBlockNum;//当前的父目录盘块号intcurrentBlockNum;//当前的盘块voidinitialize(){strcpy(fname,\0);type=Zero;size=0;fatherBlockNum=currentBlockNum=0;}};constchar*FilePath=C:\\myfiles;/*常量设置*/constintBlockSize=512;//盘块大小constintOPEN_MAX=5;//能打开最多的文件数constintBlockCount=128;//盘块数constintDiskSize=BlockSize*BlockCount;//磁盘大小constintBlockFcbCount=BlockSize/sizeof(FCB);//目录文件的最多FCB数intOpenFileCount=0;//统计当前打开文件数目structOPENLIST//用户文件打开表{intfiles;//当前打开文件数FCBf[OPEN_MAX];//FCB拷贝OPENLIST(){files=0;for(inti=0;iOPEN_MAX;i++){f[i].fatherBlockNum=-1;//为分配打开f[i].type=GENERAL;}}};structdirFile/*-------------目录文件结构---------------*/{structFCBfcb[BlockFcbCount];voidinit(int_FatherBlockNum,int_CurrentBlockNum,char*name)//父块号,当前块号,目录名{strcpy(fcb[0].fname,name);//本身的FCBfcb[0].fatherBlockNum=_FatherBlockNum;fcb[0].currentBlockNum=_CurrentBlockNum;fcb[0].type=DIRECTORY;//标记目录文件for(inti=1;iBlockFcbCount;i++){fcb[i].fatherBlockNum=_CurrentBlockNum;//标记为子项fcb[i].type=Zero;//标记为空白项}}};structDISK/**********************************************************************/{intFAT1[BlockCount];//FAT1intFAT2[BlockCount];//FAT2structdirFileroot;//根目录chardata[BlockCount-3][BlockSize];voidformat(){memset(FAT1,0,BlockCount);//FAT1memset(FAT2,0,BlockCount);//FAT2FAT1[0]=FAT1[1]=FAT1[2]=-2;//0,1,2盘块号依次代表FAT1,FAT2,根目录区FAT2[0]=FAT2[1]=FAT2[2]=-2;//FAT作备份root.init(2,2,C:\\);//根目录区memset(data,0,sizeof(data));//数据区}};FILE*fp;//磁盘文件地址char*BaseAddr;//虚拟磁盘空间基地址stringcurrentPath=C:\\;//当前路径intcurrent=2;//当前目录的盘块号stringcmd;//输入指令structDISK*osPoint;//磁盘操作系统指针charcommand[16];//文件名标识structOPENLIST*openlist;//用户文件列表指针intformat();intmkdir(char*sonfname);intrmdir(char*sonfname);intcreate(char*name);intlistshow();intdelfile(char*name);intchangePath(char*sonfname);intwrite(char*name);intexit();intopen(char*file);intclose(char*file);intread(char*file);/*------------初始化-----------------------*/intformat(){current=2;currentPath=C:\\;//当前路径osPoint-format();//打开文件列表初始化deleteopenlist;openlist=newOPENLIST;/*-------保存到磁盘上myfiles--------*/fp=fopen(FilePath,w+);fwrite(BaseAddr,sizeof(char),DiskSize,fp);fclose(fp);printf(格式化成功!!\n);return1;}intmkdir(char*sonfn