文件系统存储空间管理: 成组链接法

文件系统存储空间管理算法设计与实现

(1)目的要求

如何充分有效地利用磁盘空间、并减少管理磁盘空间而带来的时间、 空间开销,是操作系统资源管理的任务之一。本实验模拟UNIX操作系统空闲块成组链接法,使学生对磁盘空闲空间的跟踪、分配和回收方法有更深入的理解。

(2)方法原理

UNIX操作系统将磁盘空闲块进行分组,每组的第一个块记录前一组空闲块的信息,最后一组信息记录在内存超级块中。当申请内存块时,若内存超级块中记录的空闲块数大于1,则进行出栈操作,分配栈顶的块。若内存超级块中记录的空闲块数等于1,则将该空闲块中暂存的下一组空闲块信息拷贝到超级块中,再分配该空闲块。当释放内存块时,若超级块中空闲块数未满,则块号入栈,释放该块。若已满,则将超级块中信息拷贝入该空闲块,清空超级块,该空闲块号入栈。UNIX操作系统利用磁盘空闲块来暂存磁盘空闲块的信息,可以节省大量内存,同时,块号的入栈、出栈操作可以快速实现非连续空间的分配和回收。

(3)主要实验仪器及材料

PC机, windows2000以上操作系统,C\C++\Java语言编程。

(4)掌握要点

设计空白块链数据结构,设定空闲块以N个盘块为一组,已划分成M组;可以用二维数组A[M][N]或结构体链表实现块链。A[0]表示超级块,管理最后一组的空闲块。A[0][0]表示超级块中管理的空闲块数,A[0][i]表示超级块中管理的第i个空闲块(i>0)。设计文件磁盘块申请命令和文件磁盘块释放命令,并进行命令解析;设计文件信息块数据结构,用于保存文件的磁盘块构成;创建、新增、删除文件块时访问文件信息块和空白块链数据结构。

(5)实验内容

通过用户随机给定的文件创建、新增块、文件删除等命令,算法仿真实现空白块成组链接法完成磁盘空闲空间的分配和释放,并完成实验报告。

(6)实现代码

#include <iostream>
#include <string>
using namespace std;

int main() {

	//二维数组实现空闲块链
	const int Max = 20;//20组
	const int M = 5;
	const int N = 11;//每组最大10个空闲块,第0块存放本组空闲块数量,第1块指向前一组
	int A[Max][N] = {0};
	for (int i = 0; i < M;i++) {
		int count_free = 0;
		for (int j = 1; j < N; j++) {
			A[i][j] = 100*(i+1) + j;
			count_free++;//空闲块数
		}
		if (i != 0) {//不是第0组
			A[i][1] = i - 1;//A[i][1]保存前一组的下标
		}
		else {//是第0组
			A[i][1] = -1;
		}
		A[i][0] = count_free;//A[i][0]保存本组空闲块数
	}
	int last_i = 0;//指向最后一组,即指向超级块
	int last_j = 0;
	cout << "初始空闲块链:" << endl
		<< "组别 " << "空闲块数 " << "上一组"
		<<"  空闲块  空闲块\t...\t...\t...\t...\t...\t...\t..."
		<< endl;
	for (int i = 0; i < M; i++) {
		cout << i << ": \t";
		int flag = 1;
		for (int j = 0; j < N; j++) {
			cout << A[i][j] << "\t";
			last_j=j;
		}
		last_i = i;
		cout << endl;
	}
	string op="";
	string fileName="";
	int fileSize = 0;
	while (true) {
		cout<< "--\t--\t--\t---\t---\t---\t---\t---\t---\t---\t---\t---\n"
			<<"输入操作(touch/rm filename filesize):\n";
		cin >> op>>fileName>>fileSize;
		if (op == "touch") {//touch创建文件,申请空闲块
			int obtainedSize = 0;
			for (int i = 0; fileSize>obtainedSize;i++) {
				//判断有无空闲块
				if (A[last_i][0]<1&&A[last_i][1]<=0) {//全部空闲块耗尽,不再分配
					cout << "已无可用空闲空间!" << endl;
					break;
				}
				if (A[last_i][0] > 1) {//本组空闲块数大于1,分配本组的空闲块
					A[last_i][last_j] = 0;
					A[last_i][0] -= 1;
					last_j--;
				}
				//本组空闲块数不足,分配上一组的空闲块
				else {
					int tmp = A[last_i][1];
					A[last_i][last_j] = 0;
					last_i = tmp;//更新超级块,前一组成为新的超级块
					last_j = N - 1;
				}
				obtainedSize += 1;
			}
		}
		else if (op == "rm") {//rm删除文件,归还块
			int returnSize = 0;//已归还块数
			for (int i = 0;fileSize > returnSize; i++) {
				
				//判断当前组是否已满
				if ((N-1)>A[last_i][0]) {//未满,加入本组
					A[last_i][++last_j] = 100 * (last_i + 1) + last_j;
					A[last_i][0] += 1;
				}
				else {//已满,引入超级块
					int tem=last_i;
					last_i += 1;
					A[last_i][0] = 1;//将超级块空闲块数置1
					A[last_i][1] = tem;
					last_j = 1;//指向A[last_i][1]
				}
				returnSize++;
			}
		}
		else if (op == "exit") {
			break;
		}
		else {
			cout << "错误输入!" << endl;
			continue;
		}
		cout << "当前空闲块链:" << endl
			<< "组别 " << "空闲块数 " << "上一组"
			<< "  空闲块  空闲块\t...\t...\t...\t...\t...\t...\t..."
			<< endl;
		for (int i = 0; i <=last_i;i++) {//循环到超级块所在组
			cout << i << ": \t";
			if (i < last_i )
			for (int j = 0; j < N;j++) {//循环N(11)次
				cout << A[i][j] << "\t";
			}
			else if(i==last_i)
				for (int j = 0; j <=last_j;j++) {//循环到最后一个空闲块
					cout << A[i][j] << "\t";
				}
			cout << endl;
		}

		while (getchar() != '\n');//清空缓冲区
	}
	return 0;
}


(7)运行结果

初始空闲块链:
组别 空闲块数 上一组  空闲块  空闲块    ...     ...     ...     ...     ...     ...     ...
0:      10      -1      102     103     104     105     106     107     108     109     110
1:      10      0       202     203     204     205     206     207     208     209     210
2:      10      1       302     303     304     305     306     307     308     309     310
3:      10      2       402     403     404     405     406     407     408     409     410
4:      10      3       502     503     504     505     506     507     508     509     510
--      --      --      ---     ---     ---     ---     ---     ---     ---     ---     ---
输入操作(touch/rm filename filesize):
touch file1 6	//申请6个空闲块
当前空闲块链:
组别 空闲块数 上一组  空闲块  空闲块    ...     ...     ...     ...     ...     ...     ...
0:      10      -1      102     103     104     105     106     107     108     109     110
1:      10      0       202     203     204     205     206     207     208     209     210
2:      10      1       302     303     304     305     306     307     308     309     310
3:      10      2       402     403     404     405     406     407     408     409     410
4:      4       3       502     503     504
--      --      --      ---     ---     ---     ---     ---     ---     ---     ---     ---
输入操作(touch/rm filename filesize):
touch file 5	//申请5个空闲块
当前空闲块链:
组别 空闲块数 上一组  空闲块  空闲块    ...     ...     ...     ...     ...     ...     ...
0:      10      -1      102     103     104     105     106     107     108     109     110
1:      10      0       202     203     204     205     206     207     208     209     210
2:      10      1       302     303     304     305     306     307     308     309     310
3:      9       2       402     403     404     405     406     407     408     409
--      --      --      ---     ---     ---     ---     ---     ---     ---     ---     ---
输入操作(touch/rm filename filesize):
rm file3 13		//归还13个空闲块
当前空闲块链:
组别 空闲块数 上一组  空闲块  空闲块    ...     ...     ...     ...     ...     ...     ...
0:      10      -1      102     103     104     105     106     107     108     109     110
1:      10      0       202     203     204     205     206     207     208     209     210
2:      10      1       302     303     304     305     306     307     308     309     310
3:      10      2       402     403     404     405     406     407     408     409     410
4:      10      3       502     503     504     505     506     507     508     509     510
5:      2       4       602
--      --      --      ---     ---     ---     ---     ---     ---     ---     ---     ---
输入操作(touch/rm filename filesize):

在这里插入图片描述

  • 16
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
成组链是Unix操作系统中一种常用的磁盘空间管理,它将磁盘的存储空间分割成一个个固定大小的块,称为逻辑块。操作系统以逻辑块为单位进行管理和分配,对于文件存储也是以逻辑块为基本单位。成组链通过组织和管理磁盘空间,提高了文件系统的性能和效率。 在成组链中,磁盘空间被划分成多个等大小的区块,每个区块包含一个或多个物理块。这些区块按逻辑顺序排列,形成一个组。每个组都有一个数据块位图,用来记录该组中哪些逻辑块是已经分配给文件的。文件系统在创建文件时,会分配若干个逻辑块给文件,这些逻辑块可以不连续,但都来自同一组。所以文件在磁盘上的存储是通过指针链的方式完成的,这就是成组链的原理。 成组链的优点是能够减少磁盘碎片,提高文件系统的读写速度。同时,通过组织和管理磁盘空间,它也能够更加高效地利用磁盘空间,最大限度地减少存储空间的浪费。然而,成组链也有一定的局限性,它在处理大文件时可能会导致磁盘的空间利用率下降,这时可能需要采取其他的空间管理来解决这个问题。 总之,成组链是Unix操作系统中一种重要的磁盘空间管理,通过合理地组织和管理磁盘空间,提高文件系统的效率和性能,从而更好地满足用户的需求。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值