模拟实现单级目录的FAT文件系统文档格式.doc
《模拟实现单级目录的FAT文件系统文档格式.doc》由会员分享,可在线阅读,更多相关《模拟实现单级目录的FAT文件系统文档格式.doc(57页珍藏版)》请在冰点文库上搜索。
size_tfread(void*ptr,size_tsize,size_tn,FILE*stream);
size_tfwrite(constvoid*ptr,size_tsize,size_tn,FILE*stream);
13
目录
一、程序的功能 6
二、程序的基本设计思路 6
三、主要的数据结构 7
4.1创建文件流程图 9
4.3FREAD函数流程图 11
五、程序调试及其运行结果 12
六、设计总结与心得体会 15
七、附录(源程序清单) 17
一、程序的功能
该程序主要模拟实现单级目录的FAT文件系统,该系统要求能实现对文件的创建、删除、读、写、打开、关闭以及能显示目录等操作,在创建文件时,系统首先为新文件分配所需的外存空间,并且在文件系统的相应目录中,建立一个目录项,该目录项记录了新文件的文件名及其在外存中的地址等属性。
而当已经不再需要某个文件时,便可以把它从文件系统中删除。
这时执行的是与创建新文件相反的操作。
系统先从目录中找到要删除的文件项,使之成为空项,紧接着回收该文件的存储空间,用于下次分配。
通过读指针,将位于外部存储介质上的数据读入到内存缓冲区这样就实现了文件的读取,通过写指针,将内存缓冲区中的数据写入到位于外部存储介质上的文件中。
在开始使用文件时,首先必须打开文件。
这可以将文件属性信息装入内存,以便以后快速查用。
在完成文件使用后,应该关闭文件。
这不但是为了释放内存空间,而且也因为许多系统常常限制可以同时打开的文件数。
当创建文件时,先在目录表中查找是否存在此文件表,若存在则表示文件同名不能创建,否则在目录表中为此文件先建立一个目录项,保存文件的一些基本属性,如创建日期、大小、文件名等,并保存文件的首索引块扇区号,对文件读写也是先在目录项里查找文件是否存在,再根据文件的首索引块扇区号,查找对应块号中的内容对其进行读写操作,删除一个文件后回收为其分配的空间,并更新目录表、修改文件控制块。
显示目录项可以显示文件名、长度以及创建日期。
二、程序的基本设计思路
模拟实现单极目录FAT的文件系统基本思路:
在一个文件系统中对文件进行操作,实现文件的创建、读写等等操作。
在创建文件时先在目录项中进行查找,若创建的文件已存在,文件的创建首先检验目录是否为空,为空则把文件夹或文件连接到该目录下,不为空则把检查目录下是否有同名文件夹或文件,有则提示创建不成功,而文件夹打开是则把文件夹名称及其地址压入打开文件夹栈,文件关闭则把文件夹名称及其地址从打开文件夹栈中抛出。
文件夹和文件的删除,文件夹下没有打开的文件或文件没有打开才能删除,否则删除失败,每次操作成功都要更改目录和FCB信息。
该过程都保存在文件中,是对文件的操作。
本系统建于Windows平台,开发环境为WIN-TC。
三、主要的数据结构
单级目录单级索引文件系统:
常量
#defineBlockSize512
#defineDirSize32
保留扇区结构
structReserveBlock{
intsysblocknum;
/*文件系统总扇区数*/
intresblocknum;
/*保留扇区扇区数*/
intmapblocknum;
/*字节映像图扇区数*/
introotblocknum;
/*根目录区扇区数*/
charfillchar[BlockSize-4*sizeof(int)];
/*填充字节*/
};
目录结构
structDirBlock{
charfilename[11];
/*文件名限长11个字符*/
charfillchar[DirSize-4*sizeof(int)-sizeof(longint)-11];
longfilelen;
/*文件长度*/
intyear,month,day;
/*定义年月日*/
intfirstindexaddr;
/*文件首索引块扇区号*/
索引块结构
structIndexBlock{
intdataaddr[BlockSize/sizeof(int)-1];
/*数据块块号数组*/
intnextindexaddr;
/*本文件下一索引块块号*/
索引节点结构
structIndexNode{
structIndexBlockblock;
/*索引块数据*/
intblockaddr;
/*本节点索引块块号*/
structIndexNode*nextnode;
/*指向下一索引节点的指针*/};
FCB(文件控制块)结构
structFCBBlock{
intfileid;
/*文件标识*/
structDirBlockfileinfo;
/*目录信息*/
longfilepos;
/*文件读写指针*/
intfdtblockaddr;
/*目录项所在块号*/
intfdtblockindex;
/*目录项所在块内序号*/
structFCBBlock*next;
/*指向下一个文件控制块的指针*/
structIndexNode*firstindexnode;
/*指向第一个索引节点的指针*
/}
四、相关流程图
4.1创建文件流程图
主界面
Start
输入start打开文件系统
Y
N
输入creat来创建文件
输入文件名,大小,创建日期
判断是否重名
文件创建成功
文件创建失败,重新输入文件名
End
4.2删除文件流程图
创建(creat)一个文件
判断是否存在该文件
判断该文件是否被open
输入del成功删除文件
先close关闭文件
4.3FREAD函数流程图
Start
a==Null
Y
a->
fileid==fileid
N
N
Y
(a->
filepos+n)>
((a->
fileid*512)+a->
fileinfo.filelen)
N
printf("
超出空间。
\n"
)
输出字符串
输出无此fileid
a=a->
next
End
五、程序调试及其运行结果
图1
图1为欢迎界面在输入系统块的数目后产生的界面,必须先要输入start开始运行文件系统才能完成建立文件(creat),显示文件目录(list),打开文件(open),关闭文件(close),删除文件(delete),写文件块(write),读文件块(read)等等操作
图2
输入start成功打开文件系统,再输入creat来创建文件,此图为创建成功后的界面
图3
图3表示输入list显示文件目录,如图所示创建了aaa,bbb,ccc三个文件
图4
图4显示的是成功打开和成功关闭文件
图5
输入read读取文件,可以设置读文件的初始位置以及读取文件的长度.
图6输入write写文件
图7
如图所示删除aaa,bbb,ccc三个文件
六、设计总结与心得体会
通过一个学期的学习,操作系统的课程设计也要结课了,总的来说经过这门课的学习收获还是挺大的,它不但使我更了解了课本知识,巩固了课本知识,而且也使我的编程能力有了一定的提高。
这次课程设计是对操作系统的一个总结和复习的过程,课设的过程是个自我探索、自我学习的过程,其中,我们不仅学到了专业的知识,也提升了自己的学习能力。
在此次课程设计中也遇到了不少的问题和困难,但是通过自己的努力和向同学讨教都把他一一的给解决了,总之,通过这次课程设计,是我对文件系统有了更深一部的了解,让我对文件系统不再陌生,当然自己还有很多不足的地方,希望自己在以后的学习过程中不断的改进,这样才能让自己进步,才能让自己更上一层楼。
七、附录(源程序清单)
#include<
stdio.h>
string.h>
stdlib.h>
#defineRootSize2
intsysblocknum;
/*文件系统总扇区数*/
intresblocknum;
/*保留扇区扇区数*/
intfatblocknum;
/*FAT表扇区数*/
introotblocknum;
/*根目录区扇区数*/
charfillchar[BlockSize-4*sizeof(int)];
/*填充字节*/
charfilename[11];
charfillchar[DirSize-4*sizeof(int)-sizeof(longint)-11];
/*填充字节*/
longfilelen;
intyear,month,day;
/*日期*/
intfirstblockaddr;
/*文件首块扇区号*/
intfileid;
/*文件标识*/
longfilepos;
/*文件读写指针*/
intfdtblockindex;
structFCBBlock*next;
/*指向下一个文件控制块的指针*/
structReserveBlocksys1;
/*保留块*/
structFCBBlock*fcb;
/*fcb头指针*/
structDirBlockfil[32],*dir;
/*目录*/
int*fat1;
/*fat表头指针*/
char*str,*ptr;
/*读、写缓冲区首地址*/
charfillchar[BlockSize];
/*填充字符*/
FILE*fp;
/*文件指针*/
FILE*OPENSYS(char*filename)/*打开文件系统*/
{inti;
fp=fopen(filename,"
rb+"
);
fread(&
sys1,1,BlockSize,fp);
/*读保留扇区*/
fat1=(int*)malloc(sys1.fatblocknum*BlockSize);
for(i=0;
i<
sys1.fatblocknum;
i++)/*读fat表*/
fread(fat1+i*BlockSize,BlockSize,1,fp);
fseek(fp,(sys1.fatblocknum+sys1.resblocknum)*BlockSize,0);
dir=fil;
sys1.rootblocknum;
i++)/*读目录*/
fread(dir+i*BlockSize/DirSize,BlockSize,1,fp);
returnfp;
}
intCLOSESYS(FILE*stream)/*关闭文件系统*/
{inti;
fseek(stream,sys1.resblocknum*BlockSize,0);
for(i=0;
i++)/*回写fat表*/
fwrite(fat1+i*BlockSize,BlockSize,1,stream);
fseek(fp,(sys1.fatblocknum+sys1.resblocknum)*BlockSize,0);
i++)/*回写目录*/
fwrite(dir+i*BlockSize/DirSize,BlockSize,1,fp);
fclose(fp);
return0;
voidLISTDIR(void)/*显示目录*/
{inti,flag=0;
for(i=0;
32;
i++)
{if(fil[i].firstblockaddr!
=0)
{if(flag==0)
printf("
文件名大小创建日期\n"
flag=1;
printf("
%s%8ld%4d%4d%4d\n"
fil[i].filename,
fil[i].filelen,fil[i].year,fil[i].month,fil[i].day);
}}}
intFCREATE(char*filename)/*创建文件*/
{
inti,flag=0,j,k=0,flag1=0,flag2=0,a;
intn,m;
a=strlen(filename);
if(a>
10)
return1;
sys1.rootblocknum*BlockSize/DirSize;
i++)/*查找是否重名*/
if(strcmp(filename,fil[i].filename)==0)
{printf("
文件名已存在!
return3;
for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);
sys1.sysblocknum;
i++)
if(fat1[i]==0)/*查看是否有空的块*/
flag++;
if(flag==0)
{printf("
磁盘已满"
/*统计结果为0,则磁盘已满*/
return0;
}
printf("
空闲块数:
%d\n"
flag);
请输入文件长度:
"
for(j=0;
j<
j++)
if(fil[j].firstblockaddr==0)
break;
while
(1)
{scanf("
%d"
&
dir[j].filelen);
/*输入目录项中文件的长度*/
n=(dir[j].filelen/BlockSize)+(dir[j].filelen%BlockSize?
1:
0);
if(n<
0||n>
flag)/*文件长度小于0或大于空闲的空间*/
{printf("
文件太长!
printf("
请重新输入:
}
else
break;
for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);
/*分配一块空间*/
if(fat1[i]==0)
{fat1[i]=-1;
dir[j].firstblockaddr=i+1;
strcpy(dir[j].filename,filename);
/*输入文件相关的信息*/
dir[j].filename[a]='
\0'
;
输入年份:
scanf("
dir[j].year);
输入月份:
dir[j].month);
输入日期:
dir[j].day);
return(0);
intFDELETE(char*filename)/*删除文件*/
{inti,j,k,n,flag=1;
structFCBBlock*p;
p=fcb;
while(p)/*查看是否关闭了文件*/
{if(strcmp(filename,fil[p->
fdtblockindex].filename)==0)
p=p->
next;
}
for(i=0;
i++)/*查找是否存在要删除的文件*/
if(strcmp(filename,fil[i].filename)==0)
{flag=1;
break;
}
if(flag==0)
return2;
j=fil[i].first