模拟实现用位示图法管理文件存储空间的分配与回收

合集下载

基于位示图的分配与回收

基于位示图的分配与回收

基于位示图的分配与回收交通
计算机
翟高寿
位示图
利用位示图(即二维数组Map[m][n ])的一位(0/1)来表示一个内存物理块(或磁盘盘块)的使用情况,使内存所有物理块(或磁盘上所有盘块)都与一个二进制位相对应
1 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 0 0 1 0 1 0 0 1 0 1 0 ……
1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 … m-1 n-1 ……
物理块(盘块)的分配
Var Map: array [m] of integer;⇔ array [m][n] of bit ❑根据需求计算确定所需物理块数zKs
❑顺序扫描位示图,找出zKs个其值均为空闲“0”的二进制位
❑将所找到的“0”值二进制位Map[i][j]的行/列号转换为与之对应的物理块(盘块)号b:
b = n i + j
❑按物理块(或盘块)号分配物理块(或盘块),同时修改位示图和进程页表
物理块(盘块)的回收
I.将回收物理块(或盘块)的物理块(或盘块)号b
转换为位示图中的行号i和列号j:
A.i = b DIV n;
B.j = b MOD n;
II.按物理块(或盘块)号回收物理块(或盘块)III.根据回收物理块(或盘块)对应二进制位的行/列号修改位示图和进程页表
知行合一,
开拓进取!
基于位示图的分配与回收■。

用位示图管理磁盘空间的分配与回收设计报告

用位示图管理磁盘空间的分配与回收设计报告

课程设计报告( 2009--2010年度第二学期)课程名称:操作系统实验课设题目: 用位示图管理磁盘空间的分配与回收院系:控制与计算机工程学院班级:姓名:指导教师:李为设计周数: 一周成绩:2010年7月9 日一、需求分析要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。

(1)假定现有一个磁盘组,共40个柱面。

每个柱面4个磁道,每个磁道又划分成4个物理记录。

磁盘的空间使用情况用位示图表示。

位示图用若干个字构成,每一位对应一个磁盘块。

1表示占用,0表示空闲。

为了简单,假定字长为16位,其位示图如图9—1所示。

系统设一个变量S,记录磁盘的空闲块个数。

(2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出柱面号、磁道号(也即磁头号)和扇区号)。

由位示图计算磁盘的相对块号的公式如下:相对块号一字号×16+位号之后再将相对块号转换成磁盘的物理地址:由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4×4=16,故柱面号=相对块号/16的商,即柱面号=字号磁道号=(相对块号/16的余数)/4的商,即(位号/4)的商物理块号=(相对块号/16的余数)/4的余数,即(位号/4)的余数(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置0。

计算公式如下:先由磁盘地址计算相对块号:相对块号=柱面号×16+磁道号×4+物理块号再计算字号和位号:字号=相对块号/16的商,也即字号=柱面号位号=磁道号×物理块数/每磁道+物理块号(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配。

然后将分配的相对块号返回用户,并将相对块号转换成磁盘绝对地址,再显示系统各表和用户已分配的情况。

(5)设计一个回收算法,将上述已分配给用户的各盘块释放。

并显示系统各表。

位示图

位示图
1操作系统实验报告
实验名称:____________________________成绩:___________
专业班级:________姓名:_____ _____学号:0709014137
实验日期:年月日
实验报告日期:年月日
一、实验目的:实现位示图对文件存储空的管理
二、实验内容
在内存中开辟一个虚拟磁盘空间作为文件存储器,在其上实现一个简单的单用户文件系统。在退出这个简单的文件系统时,应将该虚拟文件系统保存到磁盘上,以便下次可以再将它恢复到内存的虚拟磁盘空间中。2.文件存储空间的分配可采用显式链接分配或其他的办法。3.空闲空间的管理可选择位示图或其他的办法。。#include
这种方法是在外存上建立一张位示图(bitmap),记录文件存储器的使用情况。每一位仅对应文件存储器上的一个物理块,取值0和1分别表示空闲和占用。文件存储器上的物理块依次编号为:0、1、2、…。
位示图是利用二进制的一位来表示磁盘中一个盘块的使用情况。当其值为“0”时,表示对应的盘块空闲;为“1”时表示已分配。由所有盘块对应的位构成一个集合,称为位示图。位示图也可描述为一个二维数组map:Var map:array[1...m,1...n]of bit;
·修改位示图,令map[i,j]=1。
盘块的回收
盘块的回收分两步:
·将回收盘块的盘块号转换成位于图中的行号和列号。转换公式为:
i=(b-1)DIVn+1
j=(b-1)MODn+1
·修改位示图。令map[i,j]=0。
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

操作系统课程设计-模拟设计页式存储管理的分配与回收范文

操作系统课程设计-模拟设计页式存储管理的分配与回收范文

学号:28课程设计模拟设计页式存储管理的分题目配与回收学院计算机科学与技术专业计算机科学与技术班级XX姓名XX指导教师XXX2011年01月09日课程设计任务书学生姓名: XX 专业班级:计算机0902班指导教师: XXX 工作单位:计算机科学与技术学院题目: 模拟设计页式存储管理的分配与回收初始条件:1.预备内容:阅读操作系统的内存管理章节内容,了解有关虚拟存储器、页式存储管理等概念,并体会页式管理内存的分配和回收过程。

2.实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.采用页式管理方案实施内存分配和回收。

能够处理以下的情形⑴能够输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。

⑵要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。

2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。

时间安排:设计安排一周:周1、周2:完成程序分析及设计。

周2、周3:完成程序调试及测试。

周4、周5:验收,撰写课程设计报告。

(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日武汉理工大学《操作系统》课程设计说明书模拟设计页式存储管理的分配与回收1需求分析页式管理是一种内存空间存储管理的技术,页式管理分为静态页式管理和动态页式管理。

操作系统综合实验(终结版版)

操作系统综合实验(终结版版)

位数4位数4 操作系统综合实验——位示图法管理文件存储空间的分配与回收实验组成员组长:葛加文成员:周颜安翟秋明崔建奎一、实验目的磁盘初始化时把磁盘存储空间分成许多块(扇区),这些空间可以被多个用户共享。

用户作业在执行期间常常要在磁盘上建立文件或把已经建立在磁盘上的文件删去,这就涉及到磁盘存储空间的分配和回收。

一个文件存放到磁盘上,可以组织成顺序文件(连续文件)、链接文件(串联文件)、索引文件等,因此,磁盘存储空间的分配有两种方式,一种是分配连续的存储空间,另一种是可以分配不连续的存储空间。

怎样有效地管理磁盘存储空间是操作系统应解决的一个重要问题,通过本实验使学生掌握磁盘存储空间的分配和回收算法。

二、实验内容位示图法管理文件存储空间的分配与回收(1) 为了提高磁盘存储空间的利用率,可在磁盘上组织成链接文件、索引文件,这类文件可以把逻辑记录存放在不连续的存储空间。

为了表示哪些磁盘空间已被占用,哪些磁盘空间是空闲的,可用位示图来指出。

位示图由若干字节构成,每一位与磁盘上的一块对应,“1”状态表示相应块已占用,“0”状态表示该块为空闲。

位示图的形式与实习四中的位示图一样,但要注意,对于主存储空间和磁盘存储空间应该用不同的位示图来管理,绝不可混用。

(2) 申请一块磁盘空间时,由分配程序查位示图,找出一个为“0”的位,计算出这一位对应块的磁盘物理地址,且把该位置成占用状态“1”。

为了程序编写方便,假设现在有一个盘组共8个柱面,每个柱面有两个磁道,每个磁道分成4个物理记录。

那么,当在位示图中找到某一字节的某一位为“0”时,这个空闲块对应的磁盘物理地址为:柱面号=字节号磁道号=[ ]物理记录号={ }(3) 归还一块磁盘空间时,由回收程序根据归还的磁盘物理地址计算出归还块在位示图中的对应位,把该位置成“0”。

按照(2)中假设的盘组,归还块在位示图中的位置计算如下:字节号=柱面号位数=磁道号 4+物理记录号(4) 设计申请一块磁盘空间和归还一块磁盘空间的程序。

操作系统课程设计-模拟设计页式存储管理的分配与回收范文(2)

操作系统课程设计-模拟设计页式存储管理的分配与回收范文(2)

课程设计模拟设计页式存储管理的分题目配与回收学院计算机科学与技术专业计算机科学与技术班级XX姓名XX指导教师XXX2011 年01月09 日课程设计任务书学生姓名:XX _________ 专业班级:计算机0902班____________ 指导教师:XXX ________ 工作单位:计算机科学与技术学院题目:模拟设计页式存储管理的分配与回收初始条件:1•预备内容:阅读操作系统的内存管理章节内容,了解有关虚拟存储器、页式存储管理等概念,并体会页式管理内存的分配和回收过程。

2•实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1•采用页式管理方案实施内存分配和回收。

能够处理以下的情形⑴ 能够输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。

⑵ 要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。

2•设计报告内容应说明:⑴课程设计目的与功能;⑵ 需求分析,数据结构或模块说明(功能与框图);⑶ 源程序的主要部分;⑷ 测试用例,运行结果与运行情况分析;⑸ 自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。

时间安排:设计安排一周:周1、周2:完成程序分析及设计。

周2、周3:完成程序调试及测试。

周4、周5:验收,撰写课程设计报告。

(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:模拟设计页式存储管理的分配与回收1需求分析页式管理是一种内存空间存储管理的技术,页式管理分为静态页式管理和动态页式管理。

模拟设计段式存储管理的分配与回收操作系统报告

模拟设计段式存储管理的分配与回收操作系统报告

课程设计任务书学生姓名:专业班级:计算机0指导教师:郭羽成工作单位:计算机科学与技术学院题目: 模拟设计段式存储管理的分配与回收初始条件:1.预备内容:阅读操作系统的内存管理章节内容,理解有关虚拟存储器、段式存储管理等概念,并掌握段式管理内存的分配和回收过程。

2.实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.采用段式管理方案实施内存分配和回收。

能够处理以下的情形⑴能够输入给定的内存大小,进程的个数,每个进程的段数及段大小;⑵当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后有关内存空间使用的情况;⑶显示回收后内存空间的使用情况(注意回收后的合并)。

2.设计报告内容应说明:⑴需求分析;⑵功能设计(数据结构及模块说明);⑶开发平台及源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他方法(如果有,简要说明该方法);时间安排:设计安排一周:周1、周2:完成程序分析及设计。

周2、周3:完成程序调试及测试。

周4、周5:验收、撰写课程设计报告。

(注意事项:严禁抄袭,一旦发现,一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日模拟设计段式存储管理的分配与回收1 需求分析段式存储管理是基于为用户提供一个方便灵活的程序设计环境而提出来的。

段式管理的基本思想是:把程序按内容或过程(函数)关系分成段,每段有自己的名字。

一个用户作业或进程所包含的段对应于一个二维线性虚拟空间,也就是一个二维虚拟存储器。

段式管理程序以段为单位分配内存,然后通过地址映射机构把段式虚拟地址转换成实际的内存物理地址。

和页式管理时一样,段式管理也采用只把那些经常访问的段驻留内存,而把那些在将来一段时间内不被访问的段放入外存,待需要时自动调入的方法现实二维虚拟存储器。

用位示图管理磁盘空间的分配与回收.doc

用位示图管理磁盘空间的分配与回收.doc

袇课程设计报告螈(2016--2017年度第二学期):操作系统实验薆课程名称:用位示图管理磁盘空间的分配与回收袃课设题目:控制与计算机工程学院羇院系:信安1401羅班级:黄竞昶羃姓名:贾静平薂指导教师:一周肇设计周数:莆成绩年 7月 9日螅2015莀一、需求分析蒁要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。

螆( 1)假定现有一个磁盘组,共 40 个柱面。

每个柱面 4 个磁道,每个磁道又划分成 4 个物理记录。

磁盘的空间使用情况用位示图表示。

位示图用若干个字构成,每一位对应一个磁盘块。

1 表示占用, 0 表示空闲。

为了简单,假定字长为 16 位,其位示图如图 9— 1 所示。

系统设一个变量 S,记录磁盘的空闲块个数。

莃蒁 1 膇 2 袅 3 膂 4 薁 5 薈 6 莃 7 羁 8 蚀 9 蚅肅蚀螀肆薃膃位10 11 12 13 14 15袀螃字 0 蒇 1 芅 1 薂 1 羀 1 袈 1 蚂 0 芁 1 肀 0 羄 0 莄 1 聿 1 肀 1 莅 1 袂 1 肂 01膀 1袆 2....袁 39芀图 9—1 位示图( 2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0 的位,并计算磁盘的芇物理地址 ( 即求出柱面号、磁道号 ( 也即磁头号 ) 和扇区号 ) 。

肂由位示图计算磁盘的相对块号的公式如下:蚀相对块号一字号× 16+位号荿之后再将相对块号转换成磁盘的物理地址:蚈由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4× 4= 16,故柱面号=相对块号/ 16 的商,即柱面号=字号螄磁道号= ( 相对块号/ 16 的余数 ) /4 的商,即 ( 位号/ 4) 的商蚃物理块号= ( 相对块号/ 16 的余数 ) / 4 的余数,即 ( 位号/ 4) 的余数葿( 3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置 0。

位示图方法模拟磁盘块的分配与回收

位示图方法模拟磁盘块的分配与回收

位示图方法模拟磁盘块的分配与回收题目的描述:1.要求在LINUX环境用C语言编程2.假设有一个500行500列的矩阵来表示磁盘块,状态位是1表示已经分配出去,状态位是0表示空闲块3.给这个矩阵用随机函数初始化,让其布满0和14.写程序统计有多少个空闲块?5.有一个程序文件要申请20个磁盘块,能否分配?如果可以分配,给出分配块的块号地址,块号=字号×500+位号,并修改位示图,块号从0开始编址。

6.要回收第300块和第580块,如何实现?给出位示图修改的程序在linux系统中,我想很多的朋友使用的是虚拟机,这样的话,当我们将行和列都设置为500x500的话,操作就不是很方便了,所以呢,小Q就将其修改为10X10的来演示就好了,其中的算法和思想是完全相同的。

另外一点,必须声明,在linux中使用vi编辑器进行C语言的编程,其中是不允许含有中文的,即使是中文的注释也不行。

为了,朋友们好理解,我再这里写注释的时候使用的是中文的注释,但是你在使用的时候一定要记住不能将其放入到linux环境下的vi编辑器中。

好了,我想建立文件什么的我就不用讲了,下面看下,如何解决上述的问题吧,就算是抛砖引玉吧。

/*使用变量:row表示行,col表示列*/#include <stdio.h>#include <sys/time.h>#include <fcntl.h>#define row 10#define col 10void init_random (){unsigned int ticks;struct timeval tv;int fd;gettimeofday (&tv, NULL);ticks = _sec + _usec;fd = open ("/dev/urandom", O_RDONLY);if (fd > 0){unsigned int r;int i;for (i = 0; i < 512; i++){read (fd, &r, sizeof (r));ticks += r;}close (fd);}srand (ticks);//printf("init finished ");}unsigned int new_rand (){int fd;unsigned int n = 0;fd = open ("/dev/urandom", O_RDONLY);if (fd > 0){read (fd, &n, sizeof (n));}close (fd);return n;}int statistics_free(unsigned int wst[][]){int sum_free=0;//记录空闲块个数,并初始化int i_row=0;int i_col=0;for(;i_row<row;i_row++)for(i_col=0;i_col<col;i_col++){if(wst[i_row][i_col]==0)sum_free++;}return sum_free;}void ask_space(unsigned int wst[][],int ask) {int i_row=0;int i_col=0;int t_row=0;int t_col=0;if(ask>statistics_free(wst)){printf("The space don't enough");return;}printf("The space address like this:\n");for(;i_row<row;i_row++)for(i_col=0;i_col<col;i_col++){int address=0;if(ask>0&&wst[i_row][i_col]==0){wst[i_row][i_col]=1;ask--;//计算当前的分配块号的地址address=i_row*row+i_col;printf("%d ",address);}else if(ask==0){printf("\nThe ask had request,the array is changed:\n");for(t_row=0;t_row<row;t_row++){for(t_col=0;t_col<col;t_col++)printf("%d ",wst[t_row][t_col]);printf("\n");}return;}}}void recover_space(unsigned int wst[row][col],int recover_number){int r_row=0;int r_col=0;r_row=recover_number/col;r_col=recover_number%col;if(r_row>row-1){printf("Your ask to free space don't find.");return;}wst[t_row][t_col]=0;printf("\nThe ask had request,the array is changed:\n");for(r_row=0;r_row<row;r_row++){for(r_col=0;r_col<col;r_col++)printf("%d ",wst[r_row][r_col]);printf("\n");}printf("\n");}int main (){//int n, i;//init_random ();//调用内部的接口进行设置随机种子。

操作系统-主存储器空间的分配和回收

操作系统-主存储器空间的分配和回收

实习四 主存储器空间的分配和回收一,实习题目本实习模拟在两种存储管理方式下的主存分配和回收。

第一题:在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。

[提示]:可变分区方式是按作业需要的主存空间大小来分割分区的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,假设有,则按需要量分割一个分区分配给该作业;假设无,则作业不能装入。

随着作业的装入、撤离,主存空间被分成许多个分区,有为了 说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:第一栏 第二栏其中,起址——指出一个空闲区的主存起始地址。

长度——指出从起始地址开始的一个连续空闲的长度。

状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区;另一种是“空表目”状态,表示表中对应的登记项目是空白〔无效〕,可用来登记新的空闲区〔例如,作业撤离后,它所占的区域就成了空闲区,应找一个“空表目”栏登记归还区的起址和长度且修改状态〕。

由于分区的个数不定,所以空闲区说明表中应有适量的状态为“空表目”的登记栏目,否则造成表格“溢出”无法登记。

上述的这张说明表的登记情况是按提示〔1〕中的例所装入的三个作业占用的主存区域后填写的。

(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。

有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。

为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。

为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。

为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。

(3) 采用最先适应算法〔顺序分配算法〕分配主存空间。

按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。

linux磁盘存储空间的分配与回收

linux磁盘存储空间的分配与回收

信息技术学院《嵌入式操作系统》课程综合设计报告书姓名:班级:学号:题目:磁盘存储空间的分配与回收时间: 2013年月日指导教师:摘要要把文件信息存放在存储介质上,必须先找出存储介质上可供使用的空闲块。

存储介质上某个文件不再需要时,又要收回它所占的存储空间作为空闲块。

用户作业在执行期间经常要求建立一个新文件或撤消一个不再需要的文件,因此,文件系统必须要为它们分配存储空间或收回它所占的存储空间。

如何实现存储空间的分配和收回,取决于对空闲块的管理方法,主要有两种对磁盘存储空间的分配和收回的方法:位示图法(用一张位示图(简称位图)来指示磁盘存储空间的使用情况),成组链接法(在LINIX操作系统中,把磁盘存储空间的空闲块成组链接)。

关键字:磁盘分配、磁盘回收、位示图、成组链接目录一、任务要求------------------------------------------------------------------------------------------------ 4二、设计目的------------------------------------------------------ 4三、设计方案------------------------------------------------------ 43.1 位示图法---------------------------------------------------- 53.2 成组连接法-------------------------------------------------- 53.3 主要模块 --------------------------------------------------------------------------------------------- 6四、程序流程图---------------------------------------------------- 7五、结果与调试---------------------------------------------------- 75.1程序执行结果------------------------------------------------- 75.2程序调试 ---------------------------------------------------------------------------------------------- 8六、总结---------------------------------------------------------- 8七、参考文献------------------------------------------------------ 9八、附录---------------------------------------------------------- 98.1 位示图法---------------------------------------------------- 98.2成组连接法-------------------------------------------------- 14一、任务要求通过磁盘存储空间的分配与回收,掌握磁盘存储管理的原理、软件开发方法并提高解决实际问题的能力。

操作系统-存储器的分配与回收算法实现

操作系统-存储器的分配与回收算法实现

操作系统实验报告存储器的分配与回收算法实现姓名:学号:班级:.一、实验名称及要求1、实验名称:存储器的分配与回收算法实现2、实验要求:学生应正确地设计有关的数据结构与各个功能模块,画出程序的流程图,编写程序,程序执行结果应正确。

3、实验方式:学生通过实验室的微机上机,实际调试程序。

4、实验环境:Windows操作系统环境下的个人微机C或C++程序设计语言二、实验内容1本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。

2采用最先适应法、最佳适应法、最坏适应法分配主存空间。

3当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。

若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。

4当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。

5运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。

三、实验程序#include <iostream.h>#include <malloc.h>#include <stdlib.h>typedef struct FreeLink{//定义自由链struct FreeLink *prior;char name;int start;int size;.bool flag;struct FreeLink *next;}* ptr,*head;head top;ptr p;void print(){//将内存分配情况打印到屏幕上p=top;cout<<"************************内存分配情况表************************"<<endl;cout<<"区号\t\t"<<"起始位置\t"<<"区间长度\t"<<"区间状态\t"<<endl;do{cout<<p->name<<"\t\t"<<p->start<<"\t\t"<<p->size<<"\t\t";if(p->flag==false){cout<<"空闲"<<endl;}else{cout<<"已占用"<<endl;}p=p->next;}while(p!=NULL);}void clear(){//结束操作时清空“内存”以备其他操作do{p=top;top=top->next;free(p);}while(top!=NULL);}void asc(ptr &p){//最佳适应法的内存分配函数int min;ptr op;FreeLink *fl=(FreeLink *)malloc(sizeof(FreeLink));cout<<"请输入要分配内存的进程名"<<endl;cin>>fl->name;cout<<"请输入要分配内存的大小"<<endl;cin>>fl->size;min=256;fl->flag=true;do{if(p->flag==false&&p->size<=min&&p->size>=fl->size){ min=p->size;op=p;}p=p->next;}while(p!=NULL);if(op->size>fl->size){fl->start=op->start;op->start=fl->start+fl->size;op->size=op->size-fl->size;fl->next=op;fl->prior=op->prior;op->prior->next=fl;op->prior=fl;goto flag1;}if(op->size==fl->size){op->flag=fl->flag;op->name=fl->name;free(fl);goto flag1;}cout<<"内存过小,分配失败!"<<endl;goto flag2;flag1: cout<<"分配成功!"<<endl;flag2: ;}void dec(ptr &p){//最坏适应法的内存分配函数int max;ptr op;FreeLink *fl=(FreeLink *)malloc(sizeof(FreeLink));cout<<"请输入要分配内存的进程名"<<endl;cin>>fl->name;cout<<"请输入要分配内存的大小"<<endl;cin>>fl->size;max=fl->size;fl->flag=true;do{if(p->flag==false&&p->size>=max){max=p->size;op=p;}p=p->next;}while(p!=NULL);if(op->size>fl->size){fl->start=op->start;op->start=fl->start+fl->size;op->size=op->size-fl->size;fl->next=op;fl->prior=op->prior;op->prior->next=fl;op->prior=fl;goto flag3;}if(op->size==fl->size){op->flag=fl->flag;op->name=fl->name;free(fl);goto flag3;}cout<<"内存过小,分配失败!"<<endl;goto flag4;flag3: cout<<"分配成功!"<<endl;flag4: ;}void splice(ptr &p){//若被操作的内存有相邻空闲区则将空闲区拼接合并int x;if(p->prior->flag==false&&p->next->flag==false)x=1;if((p->prior->flag==false&&p->next->flag==true)||(p->prior->flag==false&& p->next==NULL))x=2;if((p->prior->flag==true&&p->next->flag==false)||(p->prior==NULL&&p->next ->flag==false))x=3;if((p->prior->flag==true&&p->next->flag==true)||(p->prior==NULL&&p->next->flag==true)||(p->prior->flag==true&&p->next==NULL))x=4;switch(x){case 1:p->next->prior=p->prior;p->prior->next=p->next;p->prior->size=p->prior->size+p->size+p->next->size;p->prior->next=p->next->next;if(p->next->next!=NULL)p->next->next->prior=p->next->prior;free(p->next);free(p);break;case 2:if(p->next==NULL){p->prior->next=p->next;}else{p->next->prior=p->prior;p->prior->next=p->next;}p->prior->size=p->prior->size+p->size;free(p);break;case 3:if(p->prior==NULL){top=p->next;p->next->prior=NULL;p->next->start=p->start;p->next->size=p->next->size+p->size;}else{p->next->prior=p->prior;p->prior->next=p->next;p->next->start=p->start;p->next->size=p->next->size+p->size;}free(p);break;case 4:p->name='@';p->flag=false;break;}}void allocate(ptr &p){//最先适应法的内存分配函数FreeLink *fl=(FreeLink *)malloc(sizeof(FreeLink));cout<<"请输入要分配内存的进程名"<<endl;cin>>fl->name;cout<<"请输入要分配内存的大小"<<endl;cin>>fl->size;fl->flag=true;do{if(p->flag==false&&p->size>fl->size){fl->start=p->start;p->start=fl->start+fl->size;p->size=p->size-fl->size;fl->next=p;fl->prior=p->prior;p->prior->next=fl;p->prior=fl;goto a;}if(p->flag==false&&p->size==fl->size){p->flag=fl->flag;p->name=fl->name;free(fl);goto a;}p=p->next;}while(p!=NULL);cout<<"内存过小,分配失败!"<<endl;goto b;a: cout<<"分配成功!"<<endl;b: ;}void recover(ptr &p){//内存回收函数char n = ' ';cout<<"请输入要回收的内存对应的进程名";cin>>n;do{if(p->flag==true&&p->name==n){splice(p);goto c;}p=p->next;}while(p!=NULL);cout<<"内存并未分配给对应进程,回收失败!"<<endl;goto d; c: cout<<"内存回收成功!"<<endl;d: ;}int ffa(){//最先适应法char choice=' ';print();ptr pcb=(FreeLink *)malloc(sizeof(FreeLink));pcb->next=top;pcb->prior=top->prior;top->prior=pcb;pcb->start=top->start;cout<<"请输入要为系统分配的内存块名"<<endl;cin>>pcb->name;cout<<"请输入要分配内存的大小"<<endl; goto f;e: cout<<"超过内存最大容量请重新输入要分配内存的大小"<<endl; f: cin>>pcb->size;if(pcb->size>256) goto e;top->size=top->size-pcb->size;top=pcb;top->flag=true;top->next->start+=top->size;print();while(true){do{p=top->next;cout<<"请从下列选项中进行选择"<<endl;cout<<"1.分配内存"<<endl;cout<<"2.回收内存"<<endl;cout<<"3.结束操作"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3');switch(choice){case '1':allocate(p);print();break;case '2':recover(p);print();break;case '3':clear();return 0;break;}}}int bfa(){//最佳适应法char choice=' ';print();ptr pcb=(FreeLink *)malloc(sizeof(FreeLink));pcb->next=top;pcb->prior=top->prior;top->prior=pcb;pcb->start=top->start;cout<<"请输入要为系统分配的内存块名"<<endl;cin>>pcb->name;cout<<"请输入要分配内存的大小"<<endl; goto h;g: cout<<"超过内存最大容量请重新输入要分配内存的大小"<<endl; h: cin>>pcb->size;if(pcb->size>256) goto g;top->size=top->size-pcb->size;top=pcb;top->flag=true;top->next->start+=top->size;print();while(true){do{p=top->next;cout<<"请从下列选项中进行选择"<<endl;cout<<"1.分配内存"<<endl;cout<<"2.回收内存"<<endl;cout<<"3.结束操作"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3');switch(choice){case '1':asc(p);print();break;case '2':recover(p);print();break;case '3':clear();return 0;break;}}}int wfa(){//最坏适应法char choice=' ';print();ptr pcb=(FreeLink *)malloc(sizeof(FreeLink));pcb->next=top;pcb->prior=top->prior;top->prior=pcb;pcb->start=top->start;cout<<"请输入要为系统分配的内存块名"<<endl;cin>>pcb->name;cout<<"请输入要分配内存的大小"<<endl; goto j;i: cout<<"超过内存最大容量请重新输入要分配内存的大小"<<endl; j: cin>>pcb->size;if(pcb->size>256) goto i;top->size=top->size-pcb->size;top=pcb;top->flag=true;top->next->start+=top->size;print();while(true){do{p=top->next;cout<<"请从下列选项中进行选择"<<endl;cout<<"1.分配内存"<<endl;cout<<"2.回收内存"<<endl;cout<<"3.结束操作"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3');switch(choice){case '1':dec(p);print();break;case '2':recover(p);print();break;case '3':clear();return 0;break;}}}int main(){//主函数char choice = ' ';ptr free=(FreeLink *)malloc(sizeof(FreeLink));top=free;top->name='@';top->start=0;top->size=256;top->flag=false;top->prior=NULL;top->next=NULL;cout<<"***************Memory allocation and recovery algorithm***************"<<endl;cout<<"************************存储器的分配与回收算法************************"<<endl;while(true){do{cout<<"请从下列选项中进行选择"<<endl;cout<<"1.最先适应算法"<<endl;cout<<"2.最优适应算法"<<endl;cout<<"3.最坏适应算法"<<endl;cout<<"4.退出"<<endl;cout<<"请输入你的选择";cin>>choice;}while(choice!='1'&&choice!='2'&&choice!='3'&&choice!='4');switch(choice){case '1':ffa();break;case '2':bfa();break;case '3':wfa();break;case '4':return 0;break;}}}四、实验结果最先适应法最佳适应法最坏适应法五.实验总结知道了存储器的分配与回收算法实现方法,采用最先适应法、最佳适应法、最坏适应法分配主存空间。

主存储器空间的分配和回收

主存储器空间的分配和回收

主存储器空间的分配和回收实验二主存储器空间的分配和回收一、实验题目模拟在分页式管理方式下采用位示图来表示主存分配情况,实现主存空间的分配和回收。

[提示]:(1)、分页式存储器把主存分成大小相等的若干块,作业的信息也按块的大小分页,作业装入主存时可把作业的信息按页分散存放在主存的空闲块中,为了说明主存中哪些块已经被占用,哪些块是尚未分配的空闲块,可用一张位示图来指出。

位示图可由若干存储单元来构成,其中每一位与一个物理块对应,用0/1表示对应块为空闲/已占用。

(2)、假设某系统的主存被分成大小相等的64块,则位示图可用8个字节来构成,另用一单元记录当前空闲块数。

如果已有第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了,那么位示图情况如下:(3)、当要装入一个作业时,根据作业对主存的需要量,先查当前空闲块数是否能满足作业要求,若不能满足则输出分配不成功。

若能满足,则查位示图,找出为“0”的一些位,置上占用标志“1”,从“当前空闲块数”中减去本次占用块数。

按找到的计算出对应的块号,其计算公式为:块号= j 8+i其中,j表示找到的是第n个字节,I表示对应的是第n位。

根据分配给作业的块号,为作业建立一张页表,页表格式:(4) 、当一个作业执行结束,归还主存时,根据该作业的页表可以知道应归还的块号,由块号可计算出在位示图中的对应位置,把对应位的占用标志清成“0”,表示对应的块已成为空闲块。

归还的块数加入到当前空闲块数中。

由块号计算在位示图中的位置的公式如下:字节号 j=[块号/8] ([ ]表示取整)位数 i={块号/8} ({ }表示取余)(5) 设计实现主存分配和回收的程序。

假定位示图的初始状态如(2)所述,现有一信息量为5页的作业要装入,运行你所设计的分配程序,为作业分配主存且建立页表(格式如(3)所述)。

然后假定有另一作业执行结束,它占用的块号为第4,5,6和31块,运行你所设计的回收程序,收回作业归还的主存块。

parallels vms 回收磁盘空间

parallels vms 回收磁盘空间

parallels vms 回收磁盘空间摘要:一、引言二、Parallels Desktop 虚拟机磁盘空间回收方法1.利用Parallels Desktop 内置的磁盘空间管理功能2.使用第三方清理工具三、VMware ESXi thin 磁盘空间回收方法四、位示图管理磁盘空间实现磁盘块的分配与回收五、结论正文:一、引言在计算机使用过程中,磁盘空间的管理是一项重要的任务。

对于Parallels Desktop 虚拟机和VMware ESXi thin 虚拟机而言,磁盘空间的回收更是必不可少的。

本文将为您介绍几种回收磁盘空间的方法,帮助您更好地管理虚拟机磁盘空间。

二、Parallels Desktop 虚拟机磁盘空间回收方法1.利用Parallels Desktop 内置的磁盘空间管理功能Parallels Desktop 10 及以上版本中,您可以通过“文件”->“释放磁盘空间”来管理虚拟机数据使用。

此功能可以帮助您回收虚拟机部分未使用的硬盘空间,从而释放更多磁盘空间供macOS 使用。

2.使用第三方清理工具除了Parallels Desktop 内置的磁盘空间管理功能外,您还可以使用第三方清理工具,如CleanMyMac 2。

这款清理工具可以帮助您清理无用的虚拟机文件,进一步释放磁盘空间。

三、VMware ESXi thin 磁盘空间回收方法在VMware ESXi thin 虚拟机中,您可以通过以下步骤回收磁盘空间:1.使用vmware-tool首先,在虚拟机中安装vmware-tool。

安装完成后,使用vmware-tool 命令进行磁盘空间回收。

具体命令为:`vmware-tool --收回磁盘空间`。

四、位示图管理磁盘空间实现磁盘块的分配与回收位示图是一种磁盘空间管理技术,可以通过分配与回收磁盘块来实现磁盘空间的有效利用。

借助位示图技术,您可以更加精确地管理虚拟机磁盘空间,从而提高磁盘空间的利用率。

用位图法模拟管理文件存储空间分配和恢复的实现.doc

用位图法模拟管理文件存储空间分配和恢复的实现.doc

用位图法模拟管理文件存储空间分配和恢复的实现。

计算机科学与技术学院《操作系统》综合测试报告(XXXX第一学期)学生姓名:学生专业:网络工程学生班:网络班级学生人数:2名教员:12月12日,计算机科学与技术学院综合测试任务书课程设计名称《操作系统》课程设计课程设计主题模拟实现文件存储空间分配和恢复管理与位置映射方法学生姓名专业课网络编号2综合测试任务内容[问题描述]综合应用程序设计实现。

内容如下:(1)首先,我们应该深刻理解和掌握映射算法的原理。

(2)程序必须首先给出位图的初始状态。

在分配期间,参数是文件名和要分配的块数。

回收时,参数是文件名。

(3)回答信息: 当可以分配时,给出文件名和要分配的特定块号。

否则,将给出无法分配的信息。

显示位图。

(4)回收时:给出具体的回收块数。

显示位图。

[基本要求] (1)了解文件存储空间分配和恢复的基本概念,掌握几种生成文件存储空间分配和恢复的方法,认识到位图算法是管理文件存储空间分配和恢复的有效方法。

(2)通过编写程序实现位图算法,可以进一步了解位图算法的原理和执行过程,掌握位图算法的描述和应用,进一步掌握文件存储空间的分配和恢复方法。

[测试要求]对每个模块的功能进行黑盒测试,确保每个模块功能的正确性。

讲师:时间:2005年1月5日目录第一章功能需求描述11.1功能列表和描述11.2操作界面11.3界面操作1第二章系统设计描述22.1任务分解描述22.2主要数据结构设计描述22.3主要功能界面描述2第三章算法设计描述53.1主要功能和功能流程图53.1.1磁盘块分配算法流程图5 3.2.2。

磁盘块恢复算法流程图6第4章开发过程描述74.1程序源代码74.2程序中遇到的错误和错误原因74.3用于测试程序功能和测试方法的数据7第5章设计经验8附录1程序源代码9字模型第1章功能要求描述1.1功能列表和描述功能名称描述分发文件分发恢复文件退出程序1.2操作接口文件的访问和恢复1 .分发文件2 .恢复文件3。

实验六文件存储空间管理模拟--位示图

实验六文件存储空间管理模拟--位示图

实验六文件存储空间管理模拟--位示图[实验目的]通过一个简单的基于位示图的文件存储空间管理模拟算法的设计,加深理解文件系统的外存分配管理原理[实验学时]4学时[实验类型]综合性[实验内容]设计一个m行n列(自定)二维数组表示位示图结构,利用初始化操作模拟给出位示图的原始状态或者某一时刻的当前状态,设计算法:1)完成给某文件分配几个盘块的过程(返回分配的盘块号并修改位示图);2)完成某磁盘块的回收过程(根据要回收的盘块号求解出对应位示图位置并修改位示图。

注意:1可以以某文件为单位分配、回收,或者以某个磁盘块为单位分配、回收2. 可以自行选择采取连续分配或者离散分配方式,3.要求程序对不合法的条件或输入能给予恰当的处理。

[实验参考代码]略(这么简单,自己写吧)/** *@author:飞小飞* *@date:2018年11月23日 10:33* *@目的:1配与回收,在本程序中位示图 i = 0, j = 0, b = 0;开始* 采用连续存储分配方式* *功能实现:1.分配空间给文件 2.回收文件的空间 3.查看所有文件存储信息* *联系作者:******************/#include <iostream>#include <string.h>#include <stdlib.h>#include <stdio.h>using namespace std;int map[100][100];typedef struct file{char fileName[30]; /* 文件名字 */int length; /* 文件长度 */int start; /* 文件存储时的初始位置 */}file;file File[60];int line, column; /* 行列 */int fileTotalNum = 0; /* 总文件数 *//** *函数名:mapInit()* *描述:对位示图进行初始化* *参数:无* *返回值:无**/void mapInit(){int i, j;printf( "请输入行和列:" );scanf( "%d%d", &line, &column );for ( i = 0; i < line; i++ ){for ( j = 0; j < column; j++ ){map[i][j] = 0;printf( "%3d", map[i][j] );}printf( "\n" );}}/** *函数名:allocation(int fileNum)* *描述:分配空间给文件,采用连续分配方式* *参数: fileNum 第几个文件* *返回值:无**/void allocation( int fileNum ){int length = File[fileNum].length;int b[60];int i, j;int x = 0;for ( i = 0; i < line; i++ ){for ( j = 0; j < column; j++ ){if ( map[i][j] == 0 ){b[x] = i * line + j;x++;if ( x == length )break; /* 这个 break ,跳出 j 循环 */}elsex = 0;}if ( x == length )break; /* 这里 break, 跳出整个 for循环体 */ }if ( length > x )printf( "空间不足,无法分配\n" );else{File[fileNum].start = b[0];for ( int i = 0; i < x; i++ ){int x1 = b[i] / column;int y1 = b[i] % column;map[x1][y1] = 1; /* 置1 代表使用过 */}}for ( i = 0; i < line; i++ ){for ( j = 0; j < column; j++ ){printf( "%3d", map[i][j] );}printf( "\n" );}}/** *函数名:recovery(char s[])* *描述:通过文件名回收文件占用空间,并将位示图中对应标志位重新初始化为0* *参数: char s[] 文件名* *返回值:无**/void recovery( char s[] ){int cnt = -1;for ( int i = 0; i < fileTotalNum; i++ ){if ( strcmp( s, File[i].fileName ) == 0 ){cnt = i; /* 记录下第几个文件 */break;}}if ( cnt == -1 ){printf( "没有此文件,请重新输入!\n" );}int start = File[cnt].start;int length = File[cnt].length;for ( int i = start; i < start + length; i++ ){int x1 = i / column;int y1 = i % column;map[x1][y1] = 0;}for ( int i = cnt + 1; i < fileTotalNum; i++ ) /*删除文件后将其后面的文件前移覆盖原来文件 */{strcpy( File[i - 1].fileName, File[i].fileName );File[i - 1].start = File[i].start;File[i - 1].length = File[i].length;}printf( "回收成功\n" );for ( int i = 0; i < line; i++ ){for ( int j = 0; j < column; j++ ){printf( "%3d", map[i][j] );}printf( "\n" );}}/** *函数名: allocInit()* *描述:分配初始化* *参数:无* *返回值:无**/void allocInit(){printf( "请输入文件名\n" );scanf( "%s", &File[fileTotalNum].fileName ); printf( "请输入文件长度\n" );scanf( "%d", &File[fileTotalNum].length );allocation( fileTotalNum ); fileTotalNum++;}/** *函数名: recoverInit()* *描述:回收初始化* *参数:无* *返回值:无**/void recoverInit(){char name[30];printf( "请输入回收文件名\n" );scanf( "%s", &name );recovery( name );fileTotalNum--;}/** *函数名: showDir()* *描述:显示所有文件信息* *参数:无* *返回值:无**/void showDir(){if ( fileTotalNum == 0 ) /* 文件为空时 */ printf( "空文件\n" );elsefor( int i = 0; i < fileTotalNum; i++ ) {printf( "文件名:%s\n", File[i].fileName ); printf( "开始位置:%d\n", File[i].start );printf( "文件长度:%d\n", File[i].length ); }for ( int i = 0; i < line; i++ ){for ( int j = 0; j < column; j++ ){printf( "%3d", map[i][j] );}printf( "\n" );}}void page(){printf( "1为创建文件,2为回收文件,3为显示所有文件信息\n" ); printf( "请选择操作模式\n" );}int main(){int mode;mapInit();while ( 1 ){page();scanf( "%d", &mode );switch ( mode ){case1: allocInit(); break;case2: recoverInit(); break;case3: showDir(); break;default: printf( "不存在该操作,请重新输入\n" ); break;}}}。

实验四:主存空间的分配与回收实验

实验四:主存空间的分配与回收实验

0 10k主存空间的分配和回收一、实验目的设计一个可变式分区分配的存储管理方案。

并模拟实现分区的分配和回收过程。

对分区的管理法可以是下面三种算法之一: 首次适应算法 循环首次适应算法 最佳适应算法二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。

所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。

所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。

可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。

随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。

实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、循环首次适应算法、最佳适应算法三种算法来实现主存的分配与回收。

同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。

三、实验主要仪器设备和材料实验环境:硬件环境:IBM-PC 或兼容机 软件环境:Visual C++6.0四、实验原理及设计方案采用可变分区管理,使用首次或最佳适应算法实现主存的分配和回收1、可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。

随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。

为了说明那些分区是空闲的,可以用来装入新作业,必须有一张空闲说明表 例如:空闲区说明表格式如下:第二栏其中,起址——指出一个空闲区的主存起始地址,长度指出空闲区的大小。

操作系统文件存储空间管理位示图法

操作系统文件存储空间管理位示图法

操作系统文件存储空间管理位示图法#include#include#include#includeusing namespace std;struct FCB{char fname[16]; //文件名int type; //1代表普通文件2代表目录文件0表示空文件int size; //文件大小int fatherBlockNum; //当前的父目录盘块号int firstBlockNum; //该文件第一个盘块号int currentBlockNum; //当前的盘块int lastBlockNum;void initialize(){strcpy(fname,"\0");type = 0;size =0;fatherBlockNum = firstBlockNum = currentBlockNum =lastBlockNum= 0; }};/*常量设置*/const char* FilePath = "C:\\myfiles";const int BlockSize = 512; //盘块大小(可配置)const int OPEN_MAX = 5; //能打开最多的文件数const int BlockCount = BlockSize/sizeof(int); //盘块数const int DiskSize = BlockSize*BlockCount; //磁盘大小const int BlockFcbCount = BlockSize/sizeof(FCB);//目录文件的最多FCB数const int m=16; //位示图的列数const int n=BlockCount/m; //位示图的行数//const int IOBUF_SIZE = 512;//char IOBuffer[IOBUF_SIZE];int OpenFileCount = 0;struct OPENLIST //用户文件打开表{int files; //当前打开文件数FCB f[OPEN_MAX]; //FCB拷贝OPENLIST(){files=0;for(int i=0;i<open_max;i++){< bdsfid="106" p=""></open_max;i++){<>f[i].fatherBlockNum=-1;//为分配打开f[i].type=0;}}};/*-------------目录文件结构---------------*/struct dirFile{struct FCB fcb[BlockFcbCount];void init(int _FatherBlockNum,int _FirstBlockNum, int _CurrentBlockNum,int _LastBlockNum,char *name)//父块号,第一个盘块号,当前块号,目录名{strcpy(fcb[0].fname,name); //本身的FCBfcb[0].fatherBlockNum=_FatherBlockNum;fcb[0].firstBlockNum=_FirstBlockNum;fcb[0].currentBlockNum=_CurrentBlockNum;fcb[0].lastBlockNum=_LastBlockNum;fcb[0].type=2; //标记目录文件for(int i=1;i<blockfcbcount;i++)< bdsfid="125" p=""></blockfcbcount;i++)<>{fcb[i].fatherBlockNum=_CurrentBlockNum; //标记为子项fcb[i].type=0; // 标记为空白项}}};/************************************************************** ********/struct DISK{int FAT1[BlockCount]; //FAT1int FAT2[BlockCount]; //FAT2struct dirFile root; //根目录int map[n][m]; //位示图,最初都为0int check[n][m]; //check数组用于一致性检查,作为数据计数器;char data[BlockCount-5][BlockSize];void format(){memset(FAT1,0,BlockCount); //FAT1memset(FAT2,0,BlockCount); //FAT2FAT1[0]=FAT1[1]=FAT1[2]=FAT1[3]=FAT1[4]=-2; //0,1,2盘块号依次代表FAT1,FAT2,根目录区FAT2[0]=FAT2[1]=FAT2[2]=FAT2[3]=FAT2[4]=-2; //FAT作备份root.init(2,2,2,2,"G:\\");//根目录区for(int i=0;i<=BlockCount;i++) //map[0][0],map[0][1],map[0][1],map[0][2],map[0][3],map[0][4]以及check{ //对应位置为占用if(i<5){map[0][i]=0;check[0][i]=1;}else{map[i/16][i%16]=1;check[i/16][i%16]=0;}}memset(data,0,sizeof(data));//数据区}};/*-----------------全局变量--------------------------*/FILE *fp; //磁盘文件地址char * BaseAddr; //虚拟磁盘空间基地址string currentPath="G:\\"; //当前路径int current=2; //当前目录的盘块号string cmd; //输入指令struct DISK *osPoint; //磁盘操作系统指针char command[16]; //文件名标识struct OPENLIST* openlist; //用户文件列表指针/*-----------函数事先申明--------------------*/int format();int mkdir(char *sonfname);int rmdir(char *sonfname);int create(char *name);int listshow();int delfile(char *name);int changePath(char *sonfname);int write(char *name);int exit();int open(char *file);int close(char *file);int read(char *file);/*------------初始化-----------------------*/int format(){current = 2;currentPath="G:\\"; //当前路径osPoint->format();//打开文件列表初始化delete openlist;openlist=new OPENLIST;/*-------保存到磁盘上myfiles--------*/fp = fopen(FilePath,"w+");fwrite(BaseAddr,sizeof(char),DiskSize,fp);fclose(fp);printf("----------------------------------------------------------\n\n"); return 1;}/*-----------------------创建子目录-------------------*/int mkdir(char *sonfname){//判断是否有重名//寻找空白子目录项//寻找空白盘块号//当前目录下增加该子目录项//分配子目录盘块,并且初始化//修改fat表int i,temp,iFAT;struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);/*--------为了避免该目录下同名文件夹--------*/for(i = 1;i<blockfcbcount;i++)< bdsfid="216" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0 ) {printf("该文件夹下已经有同名的文件夹存在了!\n");return 0;}}//查找空白fcb序号for(i=1;i<blockfcbcount;i++)< bdsfid="225" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type==0)break;}if(i==BlockFcbCount){printf("该目录已满!请选择新的目录下创建!\n");return 0;}temp=i;for(i = 5;i < BlockCount;i++){if(osPoint->map[i/m][i%m] > 0)break;}if(i == BlockCount){printf("磁盘已满!\n");return 0;}iFAT=i;/*-------------接下来进行分配----------*/osPoint->map[iFAT/m][iFAT%m]--; //对应盘块在位示图置0;osPoint->FAT1[iFAT]=osPoint->FAT2[iFAT]= iFAT; //每个目录文件只占一块所以在文件分配表中其链接的下一块为其本身osPoint->check[iFAT/m][iFAT%m]++; //对应盘块在数据计数器中置1;//填写该分派新的盘块的参数strcpy(dir->fcb[temp].fname,sonfname);dir->fcb[temp].type=2;dir->fcb[temp].fatherBlockNum=current;dir->fcb[temp].firstBlockNum=iFAT;dir->fcb[temp].currentBlockNum=iFAT;dir->fcb[temp].lastBlockNum=iFAT;//初始化子目录文件盘块dir=(struct dirFile*)(osPoint->data [iFAT-5]); //定位到子目录盘块号dir->init (current,iFAT,iFAT,iFAT,sonfname);//iFAT是要分配的块号,这里的current用来指要分配的块的父块号printf("---------------------------------------------------------------\n\n");return 1;}/*-------删除当前目录下的文件夹--------*/int rmdir(char *sonfname){//if(子目录不存在) return error//if(子目录不是空文件夹) return error//回收子目录磁盘块号b(修改fat)//回收子目录占据目录项int i,temp,j;//确保当前目录下有该文件,并记录下该FCB下标struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);for(i=1;i<blockfcbcount;i++)< bdsfid="277" p=""></blockfcbcount;i++)<>{ //查找该目录文件if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0){break;}}temp=i;if(i==BlockFcbCount){printf("当前目录下不存在该子目录!\n");return 0;}j = dir->fcb[temp].currentBlockNum;struct dirFile *sonDir; //当前子目录的指针sonDir=(struct dirFile *)(osPoint->data [ j - 5]);for(i=1;i<="">{if(sonDir->fcb[i].type!=0){printf("该文件夹为非空文件夹,为确保安全,请清空后再删除!\n");return 0;}}/*开始删除子目录操作*/osPoint->FAT1[j] = osPoint->FAT2[j]=0; //fat清空osPoint->map[j/m][j%m]++; //位示图对应盘块置为空闲osPoint->check[j/m][j%m]--; //数据计数器对应盘块置为空闲char *p=osPoint->data[j-5]; //格式化子目录memset(p,0,BlockSize);dir->fcb[temp].initialize(); //回收子目录占据目录项printf("---------------------------------------------------------------\n\n"); return 1;}/*-----------在当前目录下创建文本文件---------------*/int create(char *name){int i,iFAT;//temp,int emptyNum = 0,isFound = 0; //空闲目录项个数struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-3]);//查看目录是否已满//为了避免同名的文本文件for(i=1;i<blockfcbcount;i++)< bdsfid="322" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type == 0 && isFound == 0){emptyNum = i;isFound = 1;}else if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0 ) {printf("无法在同一目录下创建同名文件!\n");return 0;}}if(emptyNum == 0){printf("已经达到目录项容纳上限,无法创建新文件!\n");return 0;}//查找位示图寻找空白区,用来分配磁盘块号jfor(i = 5;i<blockcount;i++)< bdsfid="341" p=""></blockcount;i++)<>{if(osPoint->map[i/m][i%m] > 0)break;}if(i==BlockCount){printf("磁盘已满!\n");return 0;}iFAT=i;/*------进入分配阶段---------*///位示图分配osPoint->map[iFAT/m][iFAT%m]--;//分配磁盘块osPoint->FAT1[iFAT] = osPoint->FAT2[iFAT] = iFAT; //文件刚刚创建时只分配一块FAT连接自身//数据计数器对应位置为占用osPoint->check[iFAT/m][iFAT%m]++;/*-----------接下来进行分配----------*///填写该分派新的盘块的参数strcpy(dir->fcb[emptyNum].fname,name);dir->fcb[emptyNum].type=1;dir->fcb[emptyNum].fatherBlockNum=current;dir->fcb[emptyNum].firstBlockNum=iFAT;dir->fcb[emptyNum].currentBlockNum=iFAT;dir->fcb[emptyNum].lastBlockNum=iFAT;dir->fcb[emptyNum].size =0;char* p = osPoint->data[iFAT -5];memset(p,'#',BlockSize);printf("----------------------------------------------------------------\n\n");return 1;}/*-------查询子目录------------*/int listshow(){int i,DirCount=0,FileCount=0;//搜索当前目录struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);for(i=1;i<blockfcbcount;i++)< bdsfid="384" p=""></blockfcbcount;i++)<>{if(dir->fcb[i].type==1){ //查找普通文件FileCount++;printf("%s 文本文件.\n",dir->fcb[i].fname);}if(dir->fcb[i].type==2){ //查找目录文件DirCount++;printf("%s 文件夹.\n",dir->fcb[i].fname);}}printf("\n该目录下共有%d 个文本文件, %d 个文件夹\n\n",FileCount,DirCount); printf("--------------------------------------------------------\n\n");return 1;}/*---------在当前目录下删除文件-----------*/int delfile(char *name){int i,temp,j;//确保当前目录下有该文件,并且记录下它的FCB下标struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-3]);for(i=1;i<="">{if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0){break;}}if(i==BlockFcbCount){printf("当前目录下不存在该文件!\n");return 0;}//从打开列表中删除close(name);printf("文件已删除!\n");temp=i;/*开始删除文件操作*/dir->fcb [temp].currentBlockNum=dir->fcb [temp].firstBlockNum;int next=dir->fcb [temp].currentBlockNum ;//查找盘块号jdo{j = dir->fcb [temp].currentBlockNum = next;next=osPoint->FAT1[j];osPoint->FAT1[j]=osPoint->FAT2[j]=0; //fat1,fat2表标记为空白osPoint->map[j/m][j%m]++; //位示图该盘块号对应位置为空闲osPoint->check[j/m][j%m]--; //数据计数器对应盘块号置为空闲char *p=osPoint->data[j - 5];memset(p,0,BlockSize); //清除原文本文件的内容}while(dir->fcb [temp].currentBlockNum!=dir->fcb [temp].lastBlockNum);dir->fcb[temp].initialize(); //type=0; //标记该目录项为空文件printf("------------------------------------------------------------\n\n");return 1;}/*--------------进入当前目录下的子目录--------------*/int changePath(char *sonfname){struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);/*回到父目录*/if(strcmp(sonfname,"..")==0){if(current==2){printf("你现已经在根目录下!\n");return 0;}current = dir->fcb[0].fatherBlockNum ;currentPath = currentPath.substr(0,currentPath.size() - strlen(dir->fcb[0].fname )-1); return 1;}/*进入子目录*/int i,temp;//确保当前目录下有该目录,并且记录下它的FCB下标for(i = 1; i < BlockFcbCount; i++){ //查找该文件if(dir->fcb[i].type==2 && strcmp(dir->fcb[i].fname,sonfname)==0 ) {temp=i;break;}}if(i==BlockFcbCount){printf("不存在该目录!\n");return 0;}//修改当前文件信息current=dir->fcb [temp].currentBlockNum ;currentPath = currentPath+dir->fcb [temp].fname +"\\";printf("-------------------------------------------------------------\n\n"); return 1;}/*--------System exit---------------------*/int exit(){//将所有文件都关闭//保存到磁盘上C:\myfilesfp=fopen(FilePath,"w+");fwrite(BaseAddr,sizeof(char),DiskSize,fp);fclose(fp);//释放内存上的虚拟磁盘free(osPoint);//释放用户打开文件表delete openlist;printf("---------------------------------------------------------\n\n");return 1;}/*-------------在指定的文件里记录信息---------------*/int write(char *name){int i;int iFAT;int FcbIndex;char *startPoint,*endPoint;struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-5]);//在打开文件列表中查找file(还需要考虑同名不同目录文件的情况)for(i=0;i<open_max;i++)< bdsfid="514" p=""></open_max;i++)<>{if(strcmp(openlist->f [i].fname,name)==0 ){if(openlist->f[i].fatherBlockNum ==current){break;}else{printf("该文件处于打开列表中,本系统只能改写当前目录下文件!\n");return 0;}}}if(i==OPEN_MAX){printf("该文件尚未打开,请先打开后写入信息!!\n");return 0;}int active=i;for(i = 1;i< BlockFcbCount;i++){ //查找该文件if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,name)==0 )FcbIndex=i;break;}}openlist->f[active].currentBlockNum=openlist->f[active].firs tBlockNum; int next=openlist->f[active].currentBlockNum;int now;while(next!=openlist->f[active].lastBlockNum){now=openlist->f[active].currentBlockNum;next=osPoint->FAT1[now];osPoint->map[next/m][next%m]++;osPoint->check[next/m][next%m]--;}int fileStartNum = openlist->f[active].currentBlockNum - 5 ; startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];printf("请输入文本以#号结束:\t");char input;while((input=getchar())!='#'){if(startPoint < endPoint){*startPoint++ = input;}else{for(i = 5;i<blockcount;i++)< bdsfid="565" p=""></blockcount;i++)<>if(osPoint->map[i/m][i%m] > 0)break;}if(i==BlockCount){printf("磁盘已满!\n");*--startPoint='#';return 0;iFAT=i;now=openlist->f[active].currentBlockNum;osPoint->map[iFAT/m][iFAT%m]--;osPoint->check[iFAT/m][iFAT%m]++;osPoint->FAT1[now]= osPoint->FAT2[now]=iFAT;openlist->f[active].currentBlockNum=iFAT;char* p = osPoint->data[iFAT -5];memset(p,'#',BlockSize);int fileStartNum = openlist->f[active].currentBlockNum - 5 ;startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];*startPoint++ = input;}}openlist->f[active].lastBlockNum=openlist->f[active].current BlockNum;dir->fcb[FcbIndex].lastBlockNum=openlist->f[active].curren tBlockNum; return 1;}/*---------选择一个打开的文件读取信息----------*/int read(char *file)int i,fileStartNum;char *startPoint,*endPoint;//struct dirFile *dir;//在打开文件列表中查找file(还需要考虑同名不同目录文件的情况)for(i=0;i<open_max;i++)< bdsfid="600" p=""></open_max;i++)<>{if(strcmp(openlist->f [i].fname,file)==0 ){if(openlist->f[i].fatherBlockNum ==current){break;}else{printf("该文件处于打开列表中,本系统只能阅读当前目录下文件!\n");return 0;}}if(i==OPEN_MAX){printf("该文件尚未打开,请先打开后读取信息!\n");return 0;}int active=i;int now;//计算文件物理地址openlist->f[active].currentBlockNum=openlist->f[active].firs tBlockNum; fileStartNum = openlist->f[active].currentBlockNum - 5 ;startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];//end_dir=(struct dirFile *)[BlockSize-1];//q=(char *)end_dir;printf("该文件的内容为: ");while((*startPoint)!='#'){if(startPoint<endpoint-1)< bdsfid="631" p=""></endpoint-1)<>putchar(*startPoint++);else{putchar(*startPoint);now=openlist->f[active].currentBlockNum;openlist->f[active].currentBlockNum=osPoint->FAT1[now];fileStartNum = openlist->f[active].currentBlockNum - 5 ;startPoint = osPoint->data[fileStartNum];endPoint = osPoint->data[fileStartNum + 1];}}printf("\n");return 1;}/*---------------当前目录下添加一个打开文件-------------------------*/int open(char *file)//打开文件{int i,FcbIndex;//确保没有打开过该文件= 相同名字+ 相同目录for(i=0;i<open_max;i++)< bdsfid="652" p=""></open_max;i++)<>{if(openlist->f[i].type ==1 && strcmp(openlist->f [i].fname,file)==0 &&openlist->f[i].fatherBlockNum == current){printf("该文件已经被打开!\n");return 0;}}//确保有空的打开文件项if(openlist->files == OPEN_MAX){printf("打开文件数目达到上限!无法再打开新文件.\n");return 0;}//确保当前目录下有该文件,并且记录下它的FCB下标struct dirFile *dir; //当前目录的指针if(current==2)dir=&(osPoint->root);elsedir=(struct dirFile *)(osPoint->data [current-3]);for(i = 1;i< BlockFcbCount;i++){ //查找该文件if(dir->fcb[i].type==1 && strcmp(dir->fcb[i].fname,file)==0 ) {FcbIndex=i;break;}}if(i==BlockFcbCount){printf("当前目录下不存在该文件!\n");return 0;}//装载新文件进入打开文件列表,(FCB信息,文件数++)openlist->f[OpenFileCount] = dir->fcb[FcbIndex]; //FCB拷贝openlist->files ++;printf("文件打开成功!\n");OpenFileCount++;return 1;}int close(char *file){//释放该文件所占内存//释放用户打开文件列表表项int i;//在打开文件列表中查找file(还需要考虑同名不同目录文件的情况) for(i=0;i<open_max;i++)< bdsfid="698" p=""></open_max;i++)<>{if((openlist->f [i].type = 1)&&(strcmp(openlist->f [i].fname,file)==0)){if(openlist->f[i].fatherBlockNum == current){break;}else{printf("该文件已打开,但未在当前目录下,无法关闭!\n"); return 0;}}}if(i==OPEN_MAX){。

模拟实现用位示图法管理文件存储空间的分配与回收

模拟实现用位示图法管理文件存储空间的分配与回收

.计算机科学与技术学院《操作系统》综合试验报告(2016/2017学年第一学期)学生姓名:学生专业:网络工程学生班级:网络班学生学号: 2指导教师:2016年12月12日计算机科学与技术学院综合试验任务书目录第一章功能需求描述 (1)1.1功能列表与说明 (1)1.2 操作界面 (1)1.3 界面操作 (1)第二章系统设计描述 (2)2.1 任务分解说明 (2)2.2主要数据结构设计说明 (2)2.3主要函数接口说明 (2)第三章算法设计描述 (5)3.1主要函数和函数的流程图 (5)3.1.1. 盘块的分配算法流程图 (5)3.2.2.盘块的回收算法流程图 (6)第四章开发过程描述 (7)4.1 程序源码 (7)4.2 程序中遇到的错误及错误原因 (7)4.3测试程序功能所用的数据和测试方法 (7)第五章设计心得体会 (8)附录1 程序源代码 (9)第一章功能需求描述1.1功能列表与说明1.2 操作界面文件的存取和回收1.分配文件2.回收文件3.退出请输入选项:1.3 界面操作如图可以很清楚的看到可以输入1 2 3 三个数分别对应分配文件、回收文件、退出三种操作。

第二章系统设计描述2.1 任务分解说明1. 位示图法系统初始化。

2 .位示图法分配与回收算法。

2.2主要数据结构设计说明1.空闲区结构体定义typedef struct node{int start_location; //空闲区对象变量的开始位置int free_number; //空闲区块数目struct node*next; //指向下一个空闲区的指针}free_link;2. 申请空间作业结构体定义typedef struct link{char office[20]; //作业名int begin_location; //作业申请空间后的开始位置int office_number; //作业申请空间区的数目struct link *next; //指向下一个申请空闲区的作业指针}office;3. 相关位示图操作的结构体定义typedef struct {free_link *p; //空间区链表指针office *q; //作业链表指针}work;2.3主要函数接口说明1.显示菜单函数void menu(){}2. 置空位示图进行初始化void zero_wst(){int i;for(i=0;i<256;i++)WST[i]=0;}3. 位示图输出显示将初始化或者申请或者回收后的位示图进行显示void print_wst(int WST[256]){}4. 已经申请空间的作业相关情况输出显示包括:作业名、申请空间的开始位置和截至位置void print_office(work *w){}5. 位示图操作的初始化包括:空闲区链表的初始化、作业链表的初始化work *start(){}6. 申请空间操作work *request(work *w,int WST[256]){}7. 回收空间操作work *delect(work *w,int WET[]){}8. 主函数void main(){int flag;work *w;zero_wst();w=start();while(1){system("cls");print_wst(WST);print_office(w);menu();cin>>flag;switch(flag){case 1:w=request(w,WST);break;case 2:w=delect(w,WST);break;case 3:exit(0);default:printf("输入错误,请重新输入!\n");break;}}}第三章算法设计描述3.1主要函数和函数的流程图3.1.1. 盘块的分配算法流程图图3-1 盘块的分配3.2.2.盘块的回收算法流程图图3-2 盘块的回收算法流程图第四章开发过程描述4.1 程序源码由于源码较长,单独附加在后面,见附录1-程序源码4.2 程序中遇到的错误及错误原因编程中几乎没有遇到什么大的问题,只有一些语法中的小错误,编译器就解决完毕。

模拟文件存储空间的管理,采用空白文件目录法和空白块链法实施空间分配

模拟文件存储空间的管理,采用空白文件目录法和空白块链法实施空间分配

实验报告课程名称 操作系统原理 实验名称 文件管理 姓 名 学号 专业班级 实验日期 成 绩 指导教师 赵安科 (①实验目的②实验原理③主要仪器设备④实验内容与步骤⑤实验数据记录与处理⑥实验结果与分析⑦问题建议)实验三 文件管理 模拟文件存储空间管理1.内容:模拟文件存储空间的管理,采用空白文件目录法和空白块链法实施空间分配。

2.思想:文件存储空间管理是文件系统的重要内容。

常用的管理思想有空白文件目录法、空白块链法和位示图法。

本实验采用前两种方法进行空间分配。

(1)空白文件目录法进行空间分配时,需要建立相关的数据结构,记录目前空白区域和已使用区域,假设开始时全部区域空闲。

当有文件需要存储时,先检查空白文件目录,找到适合区域立即分配,并修改空白文件目录表和已使用区域分配表。

为此需建立两张表格,分别记录相关数据。

空白文件目录表(初始)空白文件目录(中间)已使用区域表(中间)上述两张表的数据在系统运行中是发生变化的。

文件空闲区分配和释放算法如下图所示:图一文件空闲区分配算法图二文件空闲区回收算法(2)空白块链法进行空间分配时,需要建立链表数据结构,将空闲块按顺序加以组织,分配和回收时在链首完成,同时建立文件目录,记录文件占用空间情况。

3.要求:(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)空白文件目录法必须完成,空白块链法选做。

4.书写实验报告:①实验题目;②程序中所用的数据结构及说明;③源程序并附上必要的说明;④按照文件的创建和删除顺序,打印输出结果。

代码:#include <iostream>#include <iomanip>using namespace std;int B= 1; //空白序号int U= 100; //文件标示序号typedef struct _Black{int Bnum; int Bfirst; int Bleng; int Blast;}Black;typedef struct _Use{char Ufile[8]; int Ufirst; int Uleng; int Ulast; int Uflg;}Use;Black black[]={{0,0,100,99}}; //初始化Use use[100]={};void bubbleSort(Black a[],int m)//为了实现再次新建文件时提高分配利用率(将空白块按空白个数由从小到排序) {for (int i = 0; i < m - 1; i++){for (int j = 0; j < m - 1 - i; j++){if (a[j].Bfirst > a[j+1].Bfirst ){Black temp = a[j];a[j] = a[j+1];a[j+1] = temp;}}}}void PrintBlack(){int num=1;cout<<"########当前的空文件目录表########" <<endl;cout<<"序号首块号空白块个数末块号"<<endl;for(int i=0;i<B;i++){cout<<num<<setw(10)<<black[i].Bfirst<<setw(10)<<black[i].Bleng<<setw(10)<<black[i].B last<<endl;num++;}cout<<endl;}void PrintUse(){cout<<"#######当前的已使用文件目录#######" <<endl;cout<<"文件名首块号空白块个数末块号"<<endl;for(int i=0;i<U;i++){if(use[i].Uflg ==1){cout<<use[i].Ufile<<setw(10)<<use[i].Ufirst<<setw(10)<<use[i].Uleng<<setw(10)<<use[i].}}cout<<endl;}void Distribute(){cout<<"输入文件名和块数"<<endl;char fname[8]; //文件名int m; //块数int temp; //记录要插入的首块号(空白区中的)int t=1; //为了遍历完空白表的验证非法的输入(即块数大于空白区的所有的块数)cin>>fname>>m;for(int i= 0;i<B;i++){t++;for(int j=0; j<U; j++){if(!strcmp(fname,use[j].Ufile)){cout<<"!!!!!!!!!!!!!!!此文件名已经存在!!请换文件名!!!!!!!!!!!!!!!!"<<endl;return;}}if(black[i].Bleng>=m){temp=black[i].Bfirst;if(black[i].Bleng==m) //删除空白区for(;i<B-1;i++){black[i].Bfirst= black[i+1].Bfirst;black[i].Bleng=black[i+1].Bleng;black[i].Blast=black[i+1].Blast;}B--;}else //修改空白区{black[i].Bleng -=m;black[i].Bfirst +=m;}strcpy(use[U].Ufile ,fname);use[U].Ufirst=temp;use[U].Uleng=m;use[U].Ulast=use[U].Ufirst+use[U].Uleng-1;use[U].Uflg=1;U++;break;}else{if(t==B) //当遍历完整个空白表而且不存在小于m的空白区cout<<"由于m块数大于空闲区无法分配"<<endl;}}bubbleSort(black,B);PrintBlack();PrintUse();}void Release(){int flag=0 ; //标记输入的文件名是否存在int ufirst; //首块号int uleng; //文件快数int ulast; //文件末块char fname[8];cout<<"输入删除文件的文件名"<<endl;cin>>fname;for(int i=0;i<U;i++){if(!strcmp(fname,use[i].Ufile)){flag =1;int fT=0; //上邻标记int Tnum=0;int fB=0; //下邻标记int Bnum=0;ulast=use[i].Ulast;ufirst=use[i].Ufirst;uleng=use[i].Uleng;use[i].Uflg =-1;for(int j=0;j<B;j++) //遍历判断上下邻{if((black[j].Blast+1)==ufirst){fT=1; //存在上邻Tnum=j;}if((black[j].Bfirst-1)==ulast){fB=1; //存在下邻Bnum=j;}}if(fT&&(!fB)) //有上邻,无下邻{black[Tnum].Bleng+=uleng;black[Tnum].Blast=ulast;}if(fT&&fB) //有上邻,有下邻{black[Tnum].Bleng+=(uleng+black[Bnum].Bleng);black[Tnum].Blast=black[Bnum].Blast;for(;Bnum<B;Bnum++){black[Bnum]=black[Bnum+1];black[Bnum].Bnum=Bnum+1;}B--;}if((!fT)&&(!fB)) //无上邻,无下邻{black[B].Bnum=B;black[B].Bfirst=ufirst;black[B].Bleng=uleng;black[B].Blast=ulast;B++;}if((!fT)&&fB) //无上邻,有下邻{black[Bnum].Bleng+=uleng;black[Bnum].Bfirst=ufirst;}}}if(flag==0){cout<<"!!!!!!!!!!!!输入文件不存在!!!!!!!!!!!!"<<endl;}bubbleSort(black,B);PrintBlack();PrintUse();}void main(){cout<<"*****模拟文件存储空白文件目录*****"<<endl<<endl;PrintBlack();PrintUse();int n;while(1){cout<<"***********************************"<<endl<<endl;;cout<<"请按如下输入进行操作(分配:1 释放:2 结束:3 )";fflush( stdin );cin>>n;system( "cls ");if(n==1)Distribute();else if(n==2)Release();else if(n==3)return;else{cout<<"重新输入"<<endl;}}}(部分略) 删除f1:删除f3: 分配:f8 4:。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

合肥学院计算机科学与技术系课程设计报告20011~2012 学年第1 学期课程名称操作系统原理课程设计名称模拟实现用位示图法管理文件存储空间的分配与回收专业班级学生姓名学生学号指导教师20011 年11 月实验题目模拟用位示图法管理文件存储空间的分配与回收一、实验目的:1)理解文件存储空间的分配与回收的基本概念,掌握产生文件存储空间的分配与回收的几种方法,体会位示图算法是管理文件存储空间的分配与回收的一种行之有效的方法。

2)通过编写程序实现位示图算法,进一步理解位示图算法的原理和执行过程,掌握位示图算法的描述和应用,进一步熟练掌握文件存储空间的分配与回收的方法。

二、实验内容:(1)首先对位示图算法原理进行深刻的理解和掌握;(2)程序首先要给出位示图初态。

分配时,参数为文件名及需要分配的块数。

回收时,参数为文件名。

(3)回答信息:分配时,能够分配时,给出文件名和分配的具体块号。

否则,给出无法分配的信息。

显示位示图。

(4)回收时:给出回收的具体块号。

显示位示图。

三、实验环境Windows系统,在C++的环境下来运行这儿程序四、实验主要步骤1、初始化及使用数据结构对数组WST[]元素初始化为0。

定义以下3个链表并初始化。

空闲区结构体定义free_link、申请空间作业结构体定义office、相关位示图操作的结构体定义work。

位示图算法是利用二进制的一位来表示磁盘中的一个盘块的使用情况。

在外存上建立一张位示图(bitmap),记录文件存储器的使用情况。

每一位仅对应文件存储器上的一个物理块,取值0和1分别表示空闲和占用。

文件存储器上的物理块依次编号为:0、1、2、…。

定义为一维数组WST[],操作起来更为方便。

下表号与盘块号对应。

在输出的时候控制输出为二维形式。

2、申请空间算法首先要输入文件名和大小,查找与已存在的文件是否重名。

没有,则比较空闲区中空闲块数是否大于欲分配的块数。

有的话分配。

分配的时候该作业要记录下自己所占盘块的其实盘号和所占用的盘快数。

并修改对应盘块的位示图的值。

m=r->start_location;//空闲区的起始地址s->begin_location=r->start_location;//作业从空闲区的起始地址开始分配r->start_location=r->start_location+s->office_number;//改变空闲区空闲块数的起始地址r->free_number=r->free_number-s->office_number;//改变空间区块数的大小n=(r->start_location-1);//新的空间区的起始地址-1for(i=m;i<=n;i++)//模拟分配WST[i]=1;3、回收空间算法首先输入文件名,查找申请空间作业链表找到该作业。

找到该作业时回收该盘块。

回收时要判断盘块前后的是否为空。

决定回收的盘块来加入哪个空闲区。

(1)if((WST[s->begin_location-1]==0&&WST[s->begin_location+s->office_number]==1&&s->b egin_location-1>=0)||(WST[s->begin_location-1]==0&&s->begin_location+s->office_number== 256&&s->begin_location-1>=0)){//前面为空盘块区,后面为已分配,并入前面(2)if((WST[s->begin_location-1]==1&&WST[s->begin_location+s->office_number]==0&&s->b egin_location+s->office_number<256)||(s->begin_location==0&&WST[s->begin_location+s->off ice_number]==0&&s->begin_location+s->office_number<256)){//后面为空盘,并入后面区域(3)if(WST[s->begin_location-1]==0&&WST[s->begin_location+s->office_number]==0&&s->be gin_location-1>=0&&s->begin_location+s->office_number<256){//前后都空,合为一个空盘区(4)if((WST[s->begin_location-1]==1&&WST[s->begin_location+s->office_number]==1&&s->b egin_location-1>=0&&s->begin_location+s->office_number<256)||(s->begin_location==0&&WS T[s->begin_location+s->office_number]==1&&s->begin_location+s->office_number<256)||(WS T[s->begin_location-1]==1&&s->begin_location+s->office_number==256&&s->begin_location-1>=0)||(s->begin_location==0&&s->begin_location+s->office_number==256)){//要回收的区域自成一个空盘结点4.否否五、记录实验结果并分析1、在dos窗口界面下,我们看到的如下所示,这是程序初始化时出现的界面:2现在我们对其进行操作:选择1—分配文件,出现如下界面:我们不妨设文件名位“caozuoxitong”,并令块数为10,执行,得到如下的界面:看到从第一行的第一列一直到第一行的第九列共10个盘块均已经被分配,并且令“0”该为“1”,表示盘块已分配。

盘块的分配已经完成,下面是盘块的回收:选择2—回收文件,出现如下界面:输入我们刚刚输入的文件名“caozuoxitong”,并回车,界面如下我们看到从第一行的第一列一直到第一行的第九列已经全部变为“0”了,表示此时盘块已经回收。

按“3”退出。

对于程序中的其他的一些事项,比如盘块不够大;输入错误;找不到文件等情况,程序也给予相应的提示,用户在使用时,根据提示会很快改正相关的错误的。

六、实验总结及体会。

在做实验前,一定要将课本上的知识吃透,因为这是做实验的基础,否则,在老师讲解时就会听不懂,这将使你在做实验时的难度加大,浪费做实验的宝贵时间。

如果你不清楚,在做实验时才去摸索,这将使你极大地浪费时间,使你事倍功半。

做实验时,一定要亲力亲为,务必要将每个步骤,每个细节弄清楚,弄明白,实验后,还要复习,思考,这样,你的印象才深刻,记得才牢固,否则,过后不久你就会忘得一干二净,这还不如不做。

做实验时,老师还会根据自己的亲身体会,将一些课本上没有的知识教给我们,拓宽我们的眼界,使我们认识到这门课程在生活中的应用是那么的广泛。

实验的过程全是我们学生自己动手来完成的,这样,我们就必须要弄懂实验的原理。

在这里我深深体会到哲学上理论对实践的指导作用:弄懂实验原理,而且体会到了实验的操作能力是靠自己亲自动手,亲自开动脑筋,亲自去请教别人才能得到提高的。

我们做实验绝对不能人云亦云,要有自己的看法,这样我们就要有充分的准备,若是做了也不知道是个什么实验,那么做了也是白做。

七、源程序清单及注释。

#include"stdio.h"#include"malloc.h"#include"windows.h"#include"string.h"#include"iostream.h"int WST[256];/*************************************空闲区结构体定义start_location 空闲区对象变量的开始位置free_number 空闲区块数目next 指向下一个空闲区的指针**************************************/typedef struct node{int start_location;int free_number;struct node*next;}free_link;/*************************************申请空间作业结构体定义office[] 作业名begin_location 作业申请空间后的开始位置office_number 作业申请空间区的数目next 指向下一个申请空闲区的作业指针**************************************/typedef struct link{char office[20];int begin_location;int office_number;struct link *next;}office;/**************************************相关位示图操作的结构体定义p 空间区链表指针q 作业链表指针***************************************/typedef struct {free_link *p;office *q;}work;/*************************************** 程序菜单****************************************/void menu(){printf(" 文件的存取和回收\n");printf(" 1--分配文件\n");printf(" 2--回收文件\n");printf(" 3--退出\n\t");printf(" 请输入选项: ");}/*************************************** 置空位示图进行初始化****************************************/ void zero_wst(){int i;for(i=0;i<256;i++)WST[i]=0;}/**************************************** 位示图输出显示将初始化或者申请或者回收后的位示图进行显示*****************************************/ void print_wst(int WST[256]){int i,j=0;printf("%3s"," ");for(i=0;i<16;i++)printf("%3d",i);printf("\n");printf("%3d",0);for(i=0;i<256;i++){j++;printf("%3d",WST[i]);if(j%16==0&&i!=0&&j!=256){printf("\n");printf("%3d",j/16);}}printf("\n");}/**************************************已经申请空间的作业相关情况输出显示包括:作业名申请空间的开始位置和截至位置***************************************/void print_office(work *w){office *q;q=w->q;q=q->next;if(q!=NULL){printf("已有文件:\n");while(q!=NULL){printf("\t%s:%d-%d\n",q->office,q->begin_location,q->begin_location+q->office_number-1) ;q=q->next;}}}/*************************************位示图操作的初始化包括:空闲区链表的初始化作业链表的初始化**************************************/work *start(){free_link *p;office *q;work *w;w=(work *)malloc(sizeof(work));p=(free_link*)malloc(sizeof(free_link));p->start_location=0;p->free_number=256;p->next=NULL;q=(office *)malloc(sizeof(office));q->next=NULL;w->p=p;w->q=q;return w;}/**************************************申请空间操作***************************************/work *request(work *w,int WST[256]){int i,m,n,flag=0;free_link *p,*r,*e;//r->free_number 用于查找空闲区的块数office *q,*s,*t,*u;//s 创建新节点,存储新建文件的信息,n用于查找是否有重复节点p=w->p;r=p;q=w->q;t=q;u=q->next;printf("请输入文件名和块数:");s=(office*)malloc(sizeof(office));s->next=NULL;while(t->next!=NULL)t=t->next;scanf("%s%d",&(s->office),&(s->office_number));while(u!=NULL){if(strcmp(s->office,u->office)==0){flag=1;printf("对不起,该文件已存在!\n");free(s);break;}u=u->next;}if(flag==0){while(r!=NULL){if((r->free_number)>=(s->office_number))//用于查找空闲区中空闲块数是否大于欲分配的块数break;r=r->next;}if(r==NULL){printf("对不起,没有足够的空间分配失败!\n");free(s);}else{t->next=s;m=r->start_location;//空闲区的起始地址s->begin_location=r->start_location;//作业从空闲区的起始地址开始分配r->start_location=r->start_location+s->office_number;//改变空闲区空闲块数的起始地址r->free_number=r->free_number-s->office_number;//改变空间区块数的大小n=(r->start_location-1);//新的空间区的起始地址-1for(i=m;i<=n;i++)//模拟分配WST[i]=1;if(r->free_number==0){if(p==r){//p==r说明内存中只有一个整块的空闲区free(r);p=NULL;}else{e=p;while(e!=NULL){if(e->next==r)break;e=e->next;}e->next=r->next;free(r);}}}}w->p=p;w->q=q;return w;}/*********************************************回收空间操作**********************************************/work *delect(work *w,int WET[]){char name[20];int i;free_link *p,*r,*t;office *q,*s,*e;p=w->p;r=p;t=p;q=w->q;s=q;e=q;s=s->next;if(s==NULL){printf("没有可以回收的文件!\n");}else {printf("请输入文件名:");cin>>name;while(s!=NULL){if(strcmp(s->office,name)==0)break;s=s->next;}if(s==NULL){cout<<"对不起没有找到相关文件!\n";}else{if((WST[s->begin_location-1]==0&&WST[s->begin_location+s->office_number]==1&&s-> begin_location-1>=0)||(WST[s->begin_location-1]==0&&s->begin_location+s->office_number==256&&s->begin _location-1>=0)){while(r!=NULL){if((r->start_location+r->free_number)==s->begin_location)break;r=r->next;}r->free_number=r->free_number+s->office_number;}if((WST[s->begin_location-1]==1&&WST[s->begin_location+s->office_number]==0&& s->begin_location+s->office_number<256)||(s->begin_location==0&&WST[s->begin_location+s->office_number]==0&&s->begin_location+s->office_number<256)){while(r!=NULL){if((s->begin_location+s->office_number)==r->start_location)break;r=r->next;}r->start_location=r->start_location-s->office_number;r->free_number=r->free_number+s->office_number;}if(WST[s->begin_location-1]==0&&WST[s->begin_location+s->office_number]==0&& s->begin_location-1>=0&&s->begin_location+s->office_number<256){while(r!=NULL){if((s->begin_location+s->office_number)==r->start_location){t=r;break;}r=r->next;}r->free_number=r->free_number+s->office_number+t->free_number;free(t);}if((WST[s->begin_location-1]==1&&WST[s->begin_location+s->office_number]==1&&s-> begin_location-1>=0&&s->begin_location+s->office_number<256)||(s->begin_location==0&&WST[s->begin_location+s->office_number]==1&&s->begin_location+s->office_number<256)||(WST[s->begin_location-1]==1&&s->begin_location+s->office_number==256&&s->begin _location-1>=0)||(s->begin_location==0&&s->begin_location+s->office_number==256)){t=(free_link*)malloc(sizeof(free_link));t->next=NULL;t->start_location=s->begin_location;t->free_number=s->office_number;if(r==NULL)p=t;if(r!=NULL&&r->next==NULL){if(r->start_location<s->begin_location)r->next=t;else{t->next=r;p=t;}}if(r!=NULL&&r->next!=NULL){while(r!=NULL&&r->next!=NULL){if((r->start_location<s->begin_location)&&(s->begin_location<r->next->start_location))break;r=r->next;}t->next=r->next;r->next=t;}}for(i=s->begin_location;i<(s->begin_location+s->office_number);i++)WST[i]=0;while(e!=NULL){if(e->next==s)break;e=e->next;}e->next=s->next;free(s);}}w->p=p;w->q=q;return w;}/****************************************主函数****************************************/void main(){int flag;work *w;zero_wst();w=start();while(1){system("cls");print_wst(WST);print_office(w);menu();cin>>flag;switch(flag){case 1:w=request(w,WST);break;case 2:w=delect(w,WST);break;case 3:exit(0);default:printf("输入错误,请重新输入!\n");break;}}}。

相关文档
最新文档