实验八模拟DOS文件的建立一、上机目的:磁盘文件是磁盘上存储的重要信息,通过本实验模拟DOS文件的建立和使用情况,理解磁盘文件的物理结构。文件管理是操作系统中重要的内容之一,不同的文件系统提供了不同的物理结构,通过实验,深入理解文件的物理结构与存取方法之间的关系,以便更好的掌握文件系统的概念。二、上机内容:(1)模拟设计DOS操作系统中磁盘文件的存储结构(2)模拟设计便于直接存取的索引文件结构三、开发环境MicrosoftVisualC++环境,采用C语言编程四、分析设计(一)实验原理(1)模拟设计DOS操作系统中磁盘文件的存储结构DOS操作系统对磁盘文件的管理采用链接结构,将所有的链接指针集中在一起,存放在文件分配表(FAT)中。连接文件的第一个物理块号登记在文件目录中。其设计思想是:假定磁盘上共有N个物理块可供使用,当要存放文件时,从FAT表中寻找其值为0的项,用其对应的物理块存放文件信息,并把文件占有的各物理块用链接指针登记在FAT表中,再把文件的第一个物理块号登记在文件目录中。在DOS中FAT表的前两项用来记录磁盘的类型。而从第2项开始记录磁盘的分配情况和文件各物理块的链接情况。在FAT表中第三项的值如果为0,表示对应的第三块空闲。假设磁盘空间共有100个物理块,设计一个文件分配表FAT[100],其中每一个元素与一个物理块对应。开始时,先把FAT[100]初始化为0,前两项是用来记录磁盘的类型,所以赋常值分别为-2,-1。然后再写入文件,假设写入的文件为A,文件长度为6,要把这个文件写入磁盘,就要为这个文件分配六个物理块,所以在FAT[100]表中,找到六个空闲的物理块分配给文件A,系统就能够在磁盘上正确的保存文件A。当你要给文件A在指定的位置添加记录时,系统就要先找到一个空闲的物理块,然后把指定位置的物理块的值赋值给找到的空闲块,然后再把插入的记录插在原先指定的物理块上。这样做是为了不把在指定位置的值给覆盖掉,又能正确的插入。(2)模拟设计便于直接存取的索引文件结构在MS-DOS中通过文件目录,再沿着链查找FAT表,便可直接找到指定逻辑记录对应的物理块。在小型机或更高级的文件系统中,直接存取文件的方法是为每个文件建立一个索引表,指出各逻辑记录与物理块的对应关系。在你要索引文件时,search()函数就能够通过比较你输入的文件名是否和你之前建立的文件名相同,如果相同,就会索引出该文件,并且显示该文件的文件名、起始块号、文件长度的详细信息;如果不相同,就会输出“找不到该文件”,在索引索引点时,就要用search2()函数就通过输入的索引点是否为文件存储的最后一个块而且输入的索引点的下一个物理块为0,就可以把文件索引出来。五、参考代码:#includestring.h//使用字符串函数时需要的头文件#includestdio.h#includestdlib.hconstintFDF=-2;constintFFF=-1;constintN=100;intfilenumber;structFILEINFO//声明一个结构体类型{charname[10];//文件名为字符串intstart;//起始块号为整形intlength;//文件长度为整形};FILEINFOfile[10];//定义结构体数组,file是结构体数组名,10为数组长度intFAT[N],freespace;//FAT表和剩余空间//显示文件目录voidprintfmenu()//定义无参数返回值的printfmenu函数{inti;//定义变量i为整形printf(\t文件个数:%d\n,filenumber);//输出文件个数printf(\t文件名起始块号文件长度\n);//输出文件名,起始块号和文件长度for(i=0;ifilenumber;i++){printf(%s%d%d\n,file[i].name,file[i].start,file[i].length);}}//显示FAT表voidprintFAT()//定义无参数返回值的printFAT函数{inti;printf(\t空闲块数:%d\n,freespace);printf(\t-2代表FDF,-1代表FFF\n);for(i=0;iN;i++){printf(No.%d%d\n,i,FAT[i]);}}//搜索文件voidsearch(char*tmpname){inti;for(i=0;ifilenumber;i++){if(strcmp(file[i].name,tmpname)==0)//比较插入文件名与已存在文件名是否相同{printf(\t找到了!\n);printf(\t文件名起始块号文件长度\n);printf(%s%d%d\n,file[i].name,file[i].start,file[i].length);}else{printf(\t不存在该文件!);}}}//搜索索引点voidsearch2(intsearchpoint){inti=0;intm;if(FAT[searchpoint]==0)printf(\t该点空缺,没有文件!);elseif(FAT[searchpoint]==-1&&FAT[searchpoint-1]==-2||FAT[searchpoint]==-2&&FAT[searchpoint+1]==-1){printf(\t此处为系统空间!);}elseif(FAT[searchpoint]==-1&&FAT[searchpoint+1]==0){printf(\t找到了!此处的文件名为:%s,file[i].name);}elseif(FAT[searchpoint]!=0&&FAT[searchpoint+1]!=-1){for(m=searchpoint;;m++){if(FAT[m]==-1)printf(\t找到了!此处的文件名为:%s,file[i].name);else{printf(找不到该文件!);}break;}}elseif(FAT[searchpoint]!=0&&FAT[searchpoint+1]==-1){printf(找到了!此处的文件名为:%s,file[i].name);}}//写入文件voidwrite(char*tmpname,inttmplength){intlast,i,j;strcpy(file[filenumber].name,tmpname);//复制文件名和文件块个数file[filenumber].length=tmplength;for(i=2;iN;i++){if(FAT[i]==0){file[filenumber].start=i;//首个空闲块为文件开始块last=i;FAT[last]=FFF;break;}}for(i=1;itmplength;i++){for(j=2;jN;j++)if(FAT[j]==0){FAT[last]=j;last=j;FAT[last]=FFF;break;}}FAT[last]=FFF;//文件末存结束标记freespace-=tmplength;//改变空闲块个数filenumber++;printf(文件名和长度:%s%d\n,tmpname,tmplength);}//插入记录voidinsert(char*tmpname,intinsertpoint){inti;intlast,brpoint;for(i=0;ifilenumber;i++)//寻找要执行插入操作的文件,将其数组下标存入last{if(strcmp(file[i].name,tmpname)==0)//比较插入文件名与已存在文件名是否相同{last=i;break;}}if(insertpoint=file[last].length){printf(插入点溢出!);return;}brpoint=file[last].start;//brpoint记录当前文件扫描到的位置for(i=0;iinsertpoint;i++){brpoint=FAT[brpoint];}for(i=0;iN;i++){if(FAT[i]==0){FAT[i]=FAT[brpoint];FAT[brpoint]=i;break;}}file[last].length++;//改变空闲块个数与文件长度freespace--;printf(\t文件名和长度:%s%d\n,tmpname,file[last].length);}voidmain(){inti;chartmpname[10];//要写入文件名的字符长度inttmplength;//要写入文件长度intm;//命令filenumber=0;//初始文件个数为0for(i=0;iN;i++)//初始化FAT表{FAT[i]=0;}FAT[0]=FDF;FAT[1]=FFF;freespace=98;while(true){printf(\n);printf(****欢迎进入****\n);printf(\n);printf(模拟DOS文件的建立和使用\n);printf(0.退出\n);printf(1.写入文件2.插入文件3.显示文件目录\n);printf(4.显示FAT表5.搜索文件6.搜索索引点\n);printf(*********************************************************\n);printf(\n);printf(\t选择服务菜单:);scanf(%d,&m);switch(m){case0:exit(0);case1:printf(\t输入要写入的文件名:);scanf(%s,&tmpname);printf(\t输入要写入的文件长度:);scanf(%d,&tmplength);write(tmpname,tmplength);//调用write函数break;case2:printf(\t输入要插入的文件名:);scanf(%s,&tmpname);intinsertpoint;printf(\t输入要插入的点:);scanf(%d,&insertpoint);insert(tmpname,insertpoint);//调用插入函数break;case3:printfmenu();//调用printfmenu函数显示文件目录break;case4:printFAT();//调用printFAT函数显示FAT表break;case5:printf(\t请输入要搜索的文件名:);scanf(%s,&tmpname);search(tmpname);//调用search函数收索文件break;case6:printf(\t请输入要搜索的索引点:);intsearchpoint;//声明要插入的点scanf(%d,&searchpoint);search2(searchpoint);//调用search2函数显示索引点break;}}printFAT();}六.上机心得通过模拟DOS文件的建立和使用情况,理解磁盘文件的物理结构。对文件管理是操作系统中重要的内容之一,不同的文件系统提供了不同的物理结构有了深刻理解,同时深入理解文件的物理结构与存取方法之间的关系,以便更好的理解文件系统的概念。