实验四 文件管理报告.docx
《实验四 文件管理报告.docx》由会员分享,可在线阅读,更多相关《实验四 文件管理报告.docx(27页珍藏版)》请在冰豆网上搜索。
实验四文件管理报告
昆明理工大学信息工程与自动化学院学生实验报告
(2011—2012学年第二学期)
课程名称:
操作系统开课实验室:
信自楼4452012年5月15日
专业、年级、班
计科103
学号
201010405331
姓名
赵颜
成绩
实验项目名称
文件操作
指导教师
舒国锋
教
师
评
语
教师签名:
年月日
一、实验目的
用C或C++语言编写和调试一个简单的文件系统,模拟文件管理的基本功能。
从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
二、实验原理及基本技术路线图(方框原理图)
用C模拟实现文件系统的管理;要求设计一个多级目录结构的文件系统,能正确描述文件控制块,采用合理的外存分配方式,能实现基本的目录及文件的操作,包括创建、删除、重命名、复制、移动等功能,并对文件有一定的存取权限控制。
三、所用仪器、材料(设备名称、型号、规格等)。
计算机一台
四、实验源程序:
#include
#include
#include
#include
structOpenFileTable//打开文件表数据结构
{
longoffset;//当前文件读写指针
charfile_name[10];//文件名数组
longintfile_start;//文件起始块号
longintfile_length;//文件长度(字节)
};
structFCB_Block//FCB数据结构
{
intflag;//标志,-1表示未用,1表示文件用
charfile_name[10];//文件名数组
longintfile_date;//文件建立日期
longintfile_time;//文件建立时间
longintfile_start;//文件起始块号
longintfile_length;//文件长度(字节)
};
structSuper_Block//超级块数据结构,文件系统的分区信息,存放在0#物理块中
{
unsignedlongintfs_totalsize;//整个分区的总磁盘物理块数
unsignedlongintfs_freesize;//分区的所有空闲磁盘物理块数
unsignedintfs_blocksize;//文件系统的物理块大小(字节)
unsignedintfs_fat_start;//FAT的起始磁盘物理块号
unsignedintfs_fat_size;//FAT占用的磁盘物理块数
unsignedintfs_dir_start;//根目录的起始磁盘物理块号
unsignedintfs_dir_size;//根目录占用的磁盘物理块数
unsignedintfs_data_start;//数据区起始磁盘物理块号
unsignedlongintfs_data_size;//数据区的磁盘物理块数
};
constcharDiskName[]="FileSys.dat";//磁盘文件名
charrw_buffer[512];//读写使用的缓冲区
structFCB_Blockfilefcb[130];//读写目录使用的数据结构
structSuper_BlockFsSupBlk;//读写超级块使用的数据结构
longintfat_buffer[5000];//读写FAT使用的缓冲区,为简化在系统启动时全部装入内存,0为空闲
structOpenFileTableOFT[16];//打开文件表,当前只使用OFT[0]
unsignedintblock_size;//物理块大小(字节)
unsignedlonginttotal_disk_size;//磁盘总容量(物理块数)
unsignedinttotal_dir_size;//目录占有的物理块数
unsignedinttotal_fat_size;//FAT占有的物理块数
longintfind_fcb;//记录读FCB块的次数
FILE*fsPtr;//模拟磁盘的文件指针
/***********************磁盘块的申请***********************************/
unsignedlongintGet_Block(unsignedlongintcount)//分配count个物理快,返回首块指针,其它已经连接
{
unsignedlonginttmp,firstblk,tmpcount;
unsignedlonginti;
intflag=1;
if(count>FsSupBlk.fs_freesize)
{printf("====没有足够磁盘容量,不能分配!
====\n");return0;}
tmpcount=0;
for(i=FsSupBlk.fs_data_start;i<=FsSupBlk.fs_totalsize;i++)//建立分配链
{
if(fat_buffer[i]==0)//文件未占有,分配
{
if(flag==1)
{firstblk=i;flag=-1;}
else
{fat_buffer[tmp]=i;}
tmp=i;
fat_buffer[i]=-1;
tmpcount++;
if(tmpcount==count)//分配完成
{FsSupBlk.fs_freesize=FsSupBlk.fs_freesize-count;//减少可分配物理块
returnfirstblk;
}
}
}
return-1;//分配不成功
}
/***********************磁盘块的回收***********************************/
voidPut_Block(unsignedlongintaddr)
{unsignedlonginti,j;
intcount;
i=addr;count=0;
while(fat_buffer[i]!
=-1)
{
j=fat_buffer[i];//下一项
fat_buffer[i]=0;
count++;
i=j;
}
fat_buffer[i]=0;
FsSupBlk.fs_freesize=FsSupBlk.fs_freesize+count+1;//增加可分配物理块
return;
}
/***********************读磁盘块***********************************/
voidRead_Block(unsignedlongintaddr,char*buf)
{
if(addr>FsSupBlk.fs_totalsize)
{printf("====超出磁盘容量,不能读!
====\n");return;}
fseek(fsPtr,FsSupBlk.fs_blocksize*addr,SEEK_SET);
fread(buf,512,1,fsPtr);
return;
}
/***********************写磁盘块***********************************/
voidWrite_Block(unsignedlongintaddr,char*buf)
{
if(addr>FsSupBlk.fs_totalsize)
{printf("====超出磁盘容量,不能写!
====\n");return;}
fseek(fsPtr,FsSupBlk.fs_blocksize*addr,SEEK_SET);
fwrite(buf,512,1,fsPtr);
return;
}
/***********************格式化磁盘***********************************/
voidReal_Format()
{
unsignedlongintbcount;
longintfatval,i;
char*c;
//更改系统超级块信息
FsSupBlk.fs_totalsize=total_disk_size;
FsSupBlk.fs_blocksize=block_size;
FsSupBlk.fs_dir_start=1;
FsSupBlk.fs_dir_size=total_dir_size;
FsSupBlk.fs_fat_start=total_dir_size+1;
FsSupBlk.fs_fat_size=total_fat_size;
FsSupBlk.fs_data_start=FsSupBlk.fs_fat_start+FsSupBlk.fs_fat_size;
FsSupBlk.fs_data_size=FsSupBlk.fs_totalsize-FsSupBlk.fs_dir_size-FsSupBlk.fs_fat_size-1;
FsSupBlk.fs_freesize=FsSupBlk.fs_data_size;
//初始化目录
for(i=0;i<128;i++)filefcb[i].flag=-1;//为-1表示FCB未使用
fseek(fsPtr,512L,SEEK_SET);
fwrite(&filefcb[0],sizeof(structFCB_Block),128,fsPtr);
//初始化FAT
fatval=FsSupBlk.fs_fat_start*512;
fseek(fsPtr,fatval,SEEK_SET);//定位文件指针
bcount=FsSupBlk.fs_fat_size+FsSupBlk.fs_dir_size+1;
for(i=0;ifor(;ifwrite(&fat_buffer[0],sizeof(longint),FsSupBlk.fs_totalsize,fsPtr);
//初始化数据区
for(i=0;i<512;i++)rw_buffer[i]='';//缓冲区清空
for(i=FsSupBlk.fs_data_start;iWrite_Block(i,rw_buffer);//缓冲区写入第i块
}
/***********************新建系统磁盘文件***********************************/
voidCreate_Disk()
{
longinti;
unsignedlonginttotal;
fsPtr=fopen(DiskName,"wb+");
if(fsPtr==NULL)
{
printf("不能建立磁盘所需的文件!
\n");
exit(0);
}
//建立磁盘文件
total=total_disk_size;
for(i=0;ifwrite(rw_buffer,512,1,fsPtr);
fclose(fsPtr);
fsPtr=fopen(DiskName,"rb+");
Real_Format();
return;
}
/***********************读写系统超级块信息***********************************/
voidRead_Boot()//读取磁盘超级块数据信息
{
rewind(fsPtr);
fread(&FsSupBlk,sizeof(structSuper_Block),1,fsPtr);
return;
}
voidFileBoot()//超级块数据信息存盘
{
rewind(fsPtr);
fwrite(&FsSupBlk,sizeof(structSuper_Block),1,fsPtr);
return;
}
/***********************FAT操作***********************************/
voidLoadFat()//装载全部FAT到内存
{
fseek(fsPtr,FsSupBlk.fs_fat_start*512,SEEK_SET);
fread(fat_buffer,sizeof(longint),FsSupBlk.fs_totalsize,fsPtr);
return;
}
voidSaveFat()//FAT到文件FAT区
{
fseek(fsPtr,FsSupBlk.fs_fat_start*512,SEEK_SET);
fwrite(fat_buffer,sizeof(longint),FsSupBlk.fs_totalsize,fsPtr);
return;
}
/***********************显示超级块信息***********************************/
voidboot_dis()
{
printf("FsSupBlk.fs_totalsize=%ld\n",FsSupBlk.fs_totalsize);
printf("FsSupBlk.fs_blocksize=%d\n",FsSupBlk.fs_blocksize);
printf("FsSupBlk.fs_dir_start=%d\n",FsSupBlk.fs_dir_start);
printf("FsSupBlk.fs_dir_size=%d\n",FsSupBlk.fs_dir_size);
printf("FsSupBlk.fs_fat_start=%d\n",FsSupBlk.fs_fat_start);
printf("FsSupBlk.fs_fat_size=%d\n",FsSupBlk.fs_fat_size);
printf("FsSupBlk.fs_data_start=%d\n",FsSupBlk.fs_data_start);
printf("FsSupBlk.fs_data_size=%ld\n",FsSupBlk.fs_data_size);
printf("FsSupBlk.fs_freesize=%ld\n",FsSupBlk.fs_freesize);
}
/***********************系统初始化***********************************/
voidSys_Init()//初始化
{
fsPtr=fopen(DiskName,"rb+");
if(fsPtr==NULL)Create_Disk();
Read_Boot();
//boot_dis();
LoadFat();
return;
}
/***********************显示操作***********************************/
voiddir()//显示目录下的文件
{
inti,countFile=0;
charstr[16];
longintn,pos_dir,pos_fat;
cout<pos_dir=FsSupBlk.fs_dir_start*512;
pos_fat=FsSupBlk.fs_fat_start*512;
fseek(fsPtr,pos_dir,SEEK_SET);
while(ftell(fsPtr){
fread(&filefcb[0],sizeof(structFCB_Block),16,fsPtr);
for(i=0;i<16;i++)
if(filefcb[i].flag==1)//文件占有
{
countFile++;
n=filefcb[i].file_length;
printf("%-15s<%s>%15dbytes\n",filefcb[i].file_name,"file",n);
}
}
cout<printf("总共有%d个文件\n",countFile);
printf("系统总共有%ld个物理块可用\n\n",FsSupBlk.fs_freesize);
}
/*************************查找文件*******************************/
//查找文件,文件存在返回当前FCB数组下标,否则返回-1
intFind_File(char*filename)
{
inti;
longintpos_dir,pos_fat;
pos_dir=FsSupBlk.fs_dir_start*512;
pos_fat=FsSupBlk.fs_fat_start*512;
find_fcb=0;
fseek(fsPtr,pos_dir,SEEK_SET);
while(ftell(fsPtr){find_fcb++;
fread(&filefcb[0],sizeof(structFCB_Block),16,fsPtr);
for(i=0;i<16;i++)
if(filefcb[i].flag!
=-1)
{if(strcmp(filename,filefcb[i].file_name)==0)returni;}//文件存在
}
return-1;
}
/*************************创建文件*******************************/
voidcreate(char*fname,longintnum)//在当前目录下创建一个名字为str的文件,长度为num
{
inti,j;//true表示没有与该名字重名的文件
inttempnode;
longintpos_dir,getnum=0;
unsignedlongintblkcount;
blkcount=num/512+1;//计算需要的物理块
if(FsSupBlk.fs_freesize{
printf("\n磁盘没有足够空间,不能建立!
\n\n");
return;
}
tempnode=Find_File(fname);
if(tempnode!
=-1)//表示文件存在
{printf("\n文件已经存在,不需要建立!
\n\n");return;}
//建立文件的处理
pos_dir=FsSupBlk.fs_dir_start*FsSupBlk.fs_blocksize;
fseek(fsPtr,pos_dir,SEEK_SET);//定位到目录区
for(i=0;i{
//Read_Block(i+FsSupBlk.fs_dir_start,(char*)filefcb);
fread(&filefcb[0],sizeof(structFCB_Block),16,fsPtr);
for(j=0;j<16;j++)
if(filefcb[j].flag==-1)//找到空目录项
{
//分配空间,标记FCB数据项,并将FCB写磁盘
getnum=Get_Block(blkcount);
if(getnum==-1){printf("不能分配存储空间\n");return;}
filefcb[j].file_start=getnum;
filefcb[j].flag=1;
filefcb[j].file_length=num;
strcpy(filefcb[j].file_name,fname);
//filefcb[].file_time=
//filefcb[].file_date=
//改变磁盘FCB值
pos_dir=pos_dir+sizeof(structFCB_Block)*(i*16+j);
fseek(fsPtr,pos_dir,SEEK_SET);//定位到目录区的FCB项
fwrite(&filefcb[j],sizeof(structFCB_Block),1,fsPtr);
//Write_Block(i+FsSupBlk.fs_dir_start,(char*)filefcb);
printf("文件占用了%d个物理块\n",blkcount);
printf("系统还有%ld个物理块可用\n\n",FsSupBlk.fs_freesize);
return;
}
}
//没有FCB项,不能建立文件
cout<<"当前没有足够的目录区,不能建立文件!
"<return;
}
/*************************格式化*******************************/
voidformat()
{
charch;
cout<<"\n真希望格式化磁盘吗?
(y/n)";
cin>>ch;