操作系统 实验报告 文件管理.docx
《操作系统 实验报告 文件管理.docx》由会员分享,可在线阅读,更多相关《操作系统 实验报告 文件管理.docx(31页珍藏版)》请在冰豆网上搜索。
操作系统实验报告文件管理
昆明理工大学信息工程与自动化学院学生实验报告
(201—201学年第二学期)
课程名称:
操作系统开课实验室:
年月日
年级、专业、班
学号
姓名
成绩
实验项目名称
文件管理
指导教师
教师评语
教师签名:
年月日
一、实验目的
用C或C++语言编写和调试一个简单的文件系统,模拟文件管理的基本功能。
从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
二、实验原理及基本技术路线图(方框原理图)
用C模拟实现文件系统的管理;要求设计一个多级目录结构的文件系统,能正确描述文件控制块,采用合理的外存分配方式,能实现基本的目录及文件的操作,包括创建、删除、重命名、复制、移动等功能,并对文件有一定的存取权限控制。
功能设计:
Help显示命令帮助
dir显示当前目录下的文件和文件夹
exit退出系统
create[文件名]创建文本文件
cdir[目录名]创建文件夹
read[文件名]读取一个文件最多可同时读取五个
close[文件名]关闭一个文件
edit[文件名]编辑一个文件
cd[目录名]进子目录或者上级目录
attr[文件名]显示该文件的属性
del[文件名]删除文件
rename[文件名]重命名
编辑功能流程图
删除文件流程图创建文件流程图
核心算法:
boolFormat(void);//格式化
boolinstall(void);//装载虚拟硬盘的数据
voidlogin(void);/用户登陆
voidshowMenu(void);//显示功能菜单
boolonAction(void);//用户选择功能并执行
voidcreateFile(stringstr);//创建文件
boolread(stringstr);//读取文件
voideditFile(stringstr);//编辑文件
voidDelete(stringstr);//删除一个文件
数据结构:
/*---------常变量------*/
constunsignedintBLOCK_SIZE=512;//块长
constunsignedintDATA_BLOCK_NUM=512;//数据块数量
constunsignedintDINODE_START=4*BLOCK_SIZE;//inode起始位置
constunsignedintDINODE_SIZE=512;//inode大小
constunsignedintDINODE_NUM=32;//inode数量
constunsignedintDATASTART=(2+DINODE_NUM)*BLOCK_SIZE;//数据区的开始地址
constunsignedintACCOUNT_NUM=10;//用户数量
/*inode结构体*/
structinode{
unsignedshortdi_tag;/*inode标识*/
unsignedshortdi_number;/*关联文件数,当为0时表示删除文件,如一个目录至少包含两个文件:
"."和".."*/
unsignedshortdi_mode;/*存取模式:
0为目录,1为文件*/
unsignedshortdi_userID;/*当前inode所属用户0为根目录ID,一次下去是管理员目录、用户目录*/
unsignedshortdi_access;/*访问权限0为不允许普通用户访问(公共目录),1为允许普通用户访问*/
unsignedshortdi_size;/*文件大小,目录没有大小,值为0*/
unsignedshortdi_ctime;/*创建时间*/
unsignedshortdi_mtime;/*最后一次修改时间*/
unsignedshortdi_block[DATA_BLOCK_NUM];/*数据块块地址编号*/
};
/**超级块***/
structsuper_block{
unsignedshorts_inodes_count;/*文件系统中inode的总数*/
unsignedshorts_blocks_count;/*数据块总数*/
unsignedshorts_r_blocks_count;/*保留块总数*/
unsignedshorts_free_blocks_count;//空闲块总数
unsignedshorts_free_inodes_count;/*空闲的inode总数*/
unsignedshorts_log_block_size;/*block的大小*/
};
/**账户信息**/
structuser{
unsignedshortuser_id;//用户ID
unsignedshortuser_access;//权限
stringusername;//用户名
stringpassword;//密码
};
/**文件/目录结构**/
structdirectory{
stringname;/*目录名*/
unsignedshortd_ino;/*目录号*/
};
三、所用仪器、材料(设备名称、型号、规格等)。
计算机一台
四、实验方法、步骤
#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