资源描述
实 验 报 告
课程名称 计算机操作系统
实验名称 文件管理
班 级
学 号
姓 名
成 绩
指导教师 赵安科
实验日期 2015年6月18日
一. 实验题目:文件管理
二. 实验内容:模拟文件存储空间的管理,采用空白文件目录法和空白块链法实 施空间分配。
三. 实验说明:
文件存储空间管理是文件系统的重要内容。常用的管理思想有空白文件目录法、空白块链法和位示图法。本实验采用前两种方法进行空间分配。
(1)空白文件目录法进行空间分配时,需要建立相关的数据结构,记录目前空白区域和已使用区域,假设开始时全部区域空闲。当有文件需要存储时,先检查空白文件目录,找到适合区域立即分配,并修改空白文件目录表和已使用区域分配表。为此需建立两张表格,分别记录相关数据。
空白文件目录表(初始)
序号
首空白块号
空白快个数
物理块号
备注
1
0
100
0,1,2,……,98,99
空白文件目录(中间)
序号
首空白块号
空白块个数
物理块号
标志
1
2
4
2,3,4,5
未分配
2
9
3
9,10,11
未分配
3
25
5
25,26,27,28,29
未分配
4
39
2
39,40
未分配
5
……
……
……
未分配
文件标识
首块号
文件块个数
状态
备注
beta
0
2
占用
Alpha
6
3
占用
Toyota
12
13
占用
Sony
30
9
占用
Ford
50
4
占用
……
……
……
……
已使用区域表(中间)
上述两张表的数据在系统运行中是发生变化的。
文件空闲区分配和释放算法如下图所示:
图一 文件空闲区分配算法
图二 文件空闲区回收算法
(2) 空白块链法进行空间分配时,需要建立链表数据结构,将空闲块按顺序加以组织,分配和回收时在链首完成,同时建立文件目录,记录文件占用空间情况。
文件标识
首块号
备注
beta
0
Alpha
6
Toyota
12
Sony
30
Ford
50
……
……
四. 实验要求:
(1)自拟模拟数据演示运行结果(假定系统可用空闲块数为100)。为便于检查,建立和删除文件顺序如下:
分配文件:F1,3
分配文件:F2,5
分配文件:F3,3
分配文件:F4,8
分配文件:F5,4
分配文件:F6,2
删除文件:F1
删除文件:F2
分配文件:F7,6
删除文件:F3
分配文件:F8,4
删除文件:F5
分配文件:F9,4
……
每完成一个文件的分配和删除后,显示空白文件目录当前内容。
(2) 空白文件目录法必须完成,空白块链法选做。
五. 程序中所用数据结构及说明:
实验中,定义了两个结构体类型—SPACE(空白区)和OCCUPY(占用区),其结构如下:
struct SPACE//空白区
{
int id;//空白文件序号
int first;//首空白块号
int num;//空白块个数
int block[30];//物理块号
};
struct OCCUPY//占用区
{
char filename[20];//文件名
int firstf;//首块号
int numf;//文件块个数
int blockf[30];//物理块号
};
分别用来描述空白区和占用区的相关属性,再定义它们的结构数组OCCUPY o[20]和SPACE s[20]用来表示两个表(存储相关数据),定义变量smax和omax分别用来初始空白区文件数目和初始占用区文件数目,函数spaceprint和函数occupyprit分别用来显示空白区和占用区的情况,函数fenpei和函数shanchu分别用来分配文件和删除文件,随用户的选择可动态的分配和删除文件,并且将每次执行的结果显示出来(即空白区情况和占用区情况),用户根据两个表的情况可实时观察到操作所执行的结果及过程,最终比较实验结果可进一步加深和理解空白目录法的过程和本质。
六. 程序清单及描述:
#include<iostream.h>
#include<string.h>
int smax=1;//初始空白区文件数目
int omax=0;//初始占用区文件数目
struct SPACE//空白区
{
int id;//空白文件序号
int first;//首空白块号
int num;//空白块个数
int block[30];//物理块号
};
struct OCCUPY//占用区
{
char filename[20];//文件名
int firstf;//首块号
int numf;//文件块个数
int blockf[30];//物理块号
};
//初始化
OCCUPY o[20];
SPACE s[20]={{1,0,100,{0,1,2,3,98,99}}};
void bubble(int a[],int n)//冒泡法排序
{
int i,j,t,flag=1;
for(i=1;i<n&&flag==1;i++)
{
flag=0;
for(j=0;j<n-1;j++)
{
if(a[j]>a[j+1])
{
flag=1;
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
//空白区输出显示
void spaceprint()
{
int a[20];
for(int j=0;j<smax;j++)//将首块号排序
{
a[j]=s[j].first;
}
bubble(a,smax);
cout<<"空白文件序号\t"<<"首空白块号\t"<<"空白块个数\t"<<"物理块号\n";
for(int z=0;z<smax;z++)
{
for(int i=0;i<smax;i++)
{
if(a[z]==s[i].first)//按首块号从小到大顺序输出
{
cout<<z+1<<"\t\t"<<s[i].first<<"\t\t"<<s[i].num<<"\t\t";
cout<<s[i].first<<"—"<<s[i].first+s[i].num-1;
cout<<endl;
}
}
}
cout<<"当前空白文件数目为="<<smax<<endl;
cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
}
//占用区输出显示
void occupyprint()
{
cout<<"文件名\t首块号\t文件块个数\t物理块号\n";
for(int i=0;i<omax;i++)
{
cout<<o[i].filename<<"\t"<<o[i].firstf<<"\t"<<o[i].numf<<"\t\t";
cout<<o[i].firstf<<"—"<<o[i].firstf+o[i].numf-1;
cout<<endl;
}
cout<<"当前文件数目为="<<omax<<endl;
}
void fenpei()//分配文件
{
char filen[20]; //文件名
int size;//申请块数
int firsti=0;//中间过渡临时变量
cout<<"您执行的操作为:文件分配\n";
cout<<"请输入分配文件名:";cin>>filen;
cout<<"请输入申请块数:";cin>>size;
for(int i=0;i<smax;i++)
{
for(int j=0;j<omax;j++)
{
if(!strcmp(filen,o[j].filename))
{
cout<<"文件已分配过!\n";
return;
}
}
if(size<=0)
{
cout<<"申请块数错误!\n";
return;
}
if(i>=smax)
{
cout<<"此次分配失败!\n";
return;
}
if(s[i].num==size)//空白块个数等于申请块个数
{
firsti=s[i].first;//修改空白区
for(i;i<smax-1;i++)
{
s[i].first=s[i+1].first;
s[i].num=s[i+1].num;
}
strcpy(o[omax].filename,filen);//修改占用区
o[omax].firstf=firsti;
o[omax].numf=size;
omax++;
cout<<"文件分配成功!\n";
smax--;
break;
}
if(s[i].num>size)//空白块个数大于申请块个数
{
firsti=s[i].first;//修改空白区
s[i].first+=size;
s[i].num-=size;
strcpy(o[omax].filename,filen);//修改占用区
o[omax].firstf=firsti;
o[omax].numf=size;
omax++;
cout<<"文件分配成功!\n";
break;
}
}
spaceprint();
occupyprint();
}
void shanchu()//删除文件
{
char filen[20];//文件名
int f;//文件首块号
int n;//文件所占的块数
cout<<"您执行的操作为:文件删除\n";
cout<<"请输入删除文件名:";cin>>filen;
int exits=1;//标记,判断文件是否存在
for(int i=0;i<omax;i++)
{
if(!strcmp(o[i].filename,filen))//文件存在
{
exits=0;
int f1=0;//标记上临
int f2=0;//标记下临
int p1,p2;//存储上临、下临的序号
f=o[i].firstf;
n=o[i].numf;
for(i;i<omax-1;i++)//修改占用区
{
o[i]=o[i+1];
}
omax--;
for(int j=0;j<smax;j++)//修改空白区
{
if(s[j].first+s[j].num==f)//上临
{
f1=1;
p1=j;
}
if(s[j].first==f+n)//下临
{
f2=1;
p2=j;
}
}
//四种情况
if(f1&&!f2)//有上临无下临
{
s[p1].num+=n;
}
if(!f1&&f2)//无上临有下临
{
s[p2].first=f;
s[p2].num+=n;
}
if(f1&&f2)//既有上临又有下临
{
s[p1].num=s[p1].num+n+s[p2].num;
for(p2;p2<smax-1;p2++)
{
s[p2]=s[p2+1];
s[p2].id=p2+1;
}
smax--;
}
if(!f1&&!f2)//既无上临也无下临
{
s[smax].id=smax+1;
s[smax].first=f;
s[smax].num=n;
smax++;
}
}
}
if(exits)//文件不存在
{
cout<<"输入文件名有误!\n";
}
spaceprint();
occupyprint();
}
int main()
{
spaceprint();
occupyprint();
while(1)
{
char ch;
cout<<"************************************************************************\n";
cout<<"您可以选择以下操作:";
cout<<"1.分配文件\t"<<"2.删除文件\n";
cin>>ch;
if(ch=='1')
{
fenpei();
}
if(ch=='2')
{
shanchu();
}
if(ch!='1'&&ch!='2')
{
cout<<"输入有误,请重新输入!\n";
}
}
return 0;
}
七. 执行结果:
实验结果分析:对比实验运行结果,文件的分配过程和文件的删除过程与人工分析的结果一致,实验基本达到预期的目标。
八. 总结与体会:
在本次试验的过程中,由于前期的理论准备不足和对课本知识的掌握的不足,在编写程序的过程中,考虑的情况不全面,所写的程序结构较混乱而且可读性不强,错误较多,尤其是文件分配过程中修改空白区和占用区,文件删除过程中上下临的合并等问题,最后通过对课本的研读和画图的分析才找到错误之处进行修改得到正确结果。通过本次实验,使我对空白文件目录法有了一个深入的了解和应用,空白文件目录法是文件管理最基本的方法,其在早期的文件管理中被使用到,但这种方法仅当有少量空白文件时才有较好的效果,如果存储空间中有大量的小的空白文件,则使该目录变得很大,因而效率大为降低。其次,这种管理技术仅适用于连续文件,有一定的局限性。最后,通过本次实验,锻炼了自己的编程能力,发现了自己编程知识上的不足,和专业知识的不足,希望在以后的学习中,能注重基本知识和基本能力的培养,以使自己有一个长足的发展。
20 / 20
展开阅读全文