操作系统实验八:文件结构(MS-DOS存储、索引文件存储)

一、实验题目

1、把文件的逻辑结构转化成存储结构;
2、设计便于顺序存取和直接存取的文件存储结构。

二、实验目的

本次实验主要目的:
1、研究用户概念中的信息组织方式;
2、理解文件的逻辑结构、存取结构、存取方式之间的联系;
3、模拟设计文件的存储结构。

三、实验内容及操作步骤:

(一)模拟MS-DOS操作系统中磁盘文件存储结构:

1、算法具体内容:
1)当用户对记录式文件采用顺序存以方式时,用户总是依次地访问一个个逻辑记录,即当访问了第 i 个记录后,下次总是访问第 i+1 个记录。所以,当用户采用顺序存取方式访问文件时,只要给出访问要求(读或写)而无需再指出要访问的记录号。
2)采用链接文件结构,只有读出一个物理块信息后才能从链接字中得知下一个物理块号。所以,当用户要在文件中插入一些信息时,文件系统必须多次地请求启动磁盘读出信息才能做插入工作。
在这里插入图片描述

MS-DOS操作系统对链接文件结构作了改进, 它是把所有的链接指针集中在一起,存放在文件定位表FAT中。查找链接字时不必读出物理块信息可直接从FAT中得到。 设计思想是:
假定磁盘上共有N个物理块可供使用,FAT就有N项,初始化时为全“0”,表示对应的物理块均可使用,当要存放文件时,从FAT中寻找 为“0”的项,其对应的物理块用来存放文件信息,把文件的链接指针(指出物理块号)登记在FAT中,文件第一块块号登记在文件目录中。
在这里插入图片描述

3)假定磁盘存储空间共有32个物理块,模拟设计文件定位表FAT。文件定位表可以用一个一维数组FAT[031]来定义,其中一个元素与一个物理块对应。当FAT[i]=0时,表示第i块为空闲块 ;当FAT[i]=FFF时,表示链接文件到第i块结束 ;当在0~FFF时,其值指示链接文件中下一个 物理块号。
4)每个物理块只能存放一个逻辑记录,设计一个程序把文件的逻辑结构模拟转换成MS-DOS的链接结构。
要求保存一个已经在主存中的文件时,给出文件名和文件的逻辑记录长度及个数,对一个已经保存的文件,允许用户插入新记录。用键盘输入来模拟用户的要求,输入信息为:
“存” 文件名 逻辑记录长度 逻辑记录个数
“插入” 文件名 逻辑记录号模拟程序的算法如下图所示:
在这里插入图片描述

5)假设系统中已经有两个链接文件,其链接情况由 FAT 表指出(链接情况学生自定),现又要保存一个新文件,然后对已保存的文件插入一个新记录。运行你所设计的程序,观察其结果。

2、具体实现步骤:

(1)程序中使用的数据结构及符号说明
算法的实现主要是依靠一些数组来完成,同时用一些变量进行辅助。算法中使用到的变量和数组的名称及其含义如下表所示:
变量名称	变量类型	变量含义FAT[]	int*	文件定位表 FATleftblocks	int	主存剩余块的数量name[]	string*	文件名列表start[]	int*	文件起始块号filenum	int	文件数量

(2)算法的具体步骤
本题是根据读取的指令来进行操作,主要就是分为四个功能,分别是存文件、文件中插入块、展示信息和退出系统。首先是要从键盘输入读取指令,为了兼容性和处理方便,把指令设置成英文单词读入,然后根据读入的内容来区分具体的指令,接下来的处理分为四部分进行,算法描述也分为四部分来叙述。文件定位表的第 0 位设置成-2,代表 FDF;第 1 位设置成-1,代表 FFF 表示所有文件的结束,其他位置标记为 0,表示空闲块,如果是大于 0 的数字表示下一个逻辑块的位置。
测试结束退出系统:读取到这个指令的时候就不需要进行其他操作,直接返回主函数即可。
存文件:首先从键盘输入读取文件名,然后在文件列表中寻找是不是有同名的文件,如果有则存文件失败。接着读取文件的逻辑记录长度和逻辑记录个数,判断剩余的内存块是否够存储这个文件,如果不够存储则结束存文件并输出错误信息。如果内存块足够存储这个文件,那么就在文件列表里面加入这个文件,然后对这些逻辑块逐个存储,对每个逻辑块,首先在内存中找到一个空闲的位置,记录下这个位置,表示当前文件块存储在这个位置上,然后将上一个文件逻辑块的指针指向当前位置,从而形成链状结构。如果这个逻辑块是第一个被存储的逻辑块,也就是文件的起始块,那么记录这个文件的起始块号。完成文件定位表的索引记录后要将搜索的索引加一,表示从下一个位置开始搜索,空出当前位置,然后更新剩余块的数量,继续存储下一个文件逻辑块。记录了所有逻辑块的指针以后,将最后一个逻辑块的指针指向统一的文件结束块,索引为 1,这样就结束了一个文件的存储。
文件中插入块:首先读取要插入的文件名,然后在文件列表中搜索是否有这个文件,如果没有则插入失败。找到这个文件以后记录这个文件在文件列表中的位置,然后读取需要插入的位置,检查内存是否还有空间插入一个块,如果没有空间了插入失败。接着,在内存块中找一个空闲的块来存放这个要插入的逻辑块,然后通过这个文件的文件起始块号和文件索引表定位到要插入位置的前一个块,将当前要插入块的文件定位表内容设置成原来要插入位置的下一个块,指向下一个位置,然后将刚刚定位到的块的文件定位表内容修改为插入的这个块的索引,类似于指针的操作,将这个块插入相应的位置,加入了原来的文件逻辑块序列中。如果要把这个逻辑块插入文件的第一个位置,那么还是先把他存到一个位置上,然后修改他的文件定位表的内容,指向原来的第一个块,接着把他的位置存放到文件起始表中即可。然后更新剩余块的数量,输出成功信息即可。
输出信息:按照要求输出当前所有的文件目录和他们对应的起始块号即可,接着输出文件定位表的内容。

3、算法实现的源代码:

//MS-DOS 磁盘文件存储结构
#include <iostream>
using namespace std;
//文件定位表 FAT
int FAT[32];
//主存剩余块的数量
int leftblocks = 32;
//文件名列表和文件起始块号一一对应
//文件名列表
string name[32];
//文件起始块号
int start[32];
//文件数量
int filenum = 0;

//初始化函数,重置 FAT
void init() {
    for(int i = 0; i < 32; i++)
        FAT[i] = 0;
//将第一位设置为 FDF
    FAT[0] = -2;
//将第二位设置成所有文件的结束 FFF
    FAT[1] = -1;
    leftblocks -= 2;
}

//寻找相同文件名的条目
//找到就返回在文件目录中的索引
int FindFile(string filename) {
    for(int i = 1; i <= filenum; i++)
        if(name[i] == filename)
            return i;
    return 0;
}

//存文件操作
void save() {
    string filename;
    cout << "请输入文件名: ";
    cin >> filename;
//首先寻找是不是有同名的文件
//如果有则不能重复插入
    int  num;
    cout << "请输入逻辑记录长度: ";
    cin >> num;
    if(FindFile(filename) != 0) {
        cout << "********存在同名文件,存操作执行失败!********" << endl;
        return;
    }
//检查内存剩余的空间是不是够存储
    if(num > leftblocks) {
        cout << "********存储的文件过大,无法存储!********" << endl;
        return;
    }
//记录文件名称
    name[++filenum] = filename;
    int pos = 0, lastpos;
//找 num 个空的内存块来存储,同时更新索引
    for(int i = 1; i <= num; i++) {
//找到一个空的位置
        while(FAT[pos] != 0)
            pos = (pos + 1) % 32;
//如果是文件的起始块号则直接存储下一个块的索引
        if(i == 1)
            start[filenum] = pos;
//不是起始块则将上一个块的索引设置成当前的地址
        else
            FAT[lastpos] = pos;
//记录当前地址,实际的复制内容由下一个块的地址决定
        lastpos = pos;
//从下一个块开始找,空出当前地址留待使用
        pos++;
//剩余的块少一个
        leftblocks--;
    }
//将文件的结尾执行统一的结束符 FFF
    FAT[lastpos] = 1;
    cout << "********文件存储成功!********" << endl;
}

//插入 文件操作
void insert() {
    string filename;
    cout << "请输入文件名:";
    cin >> filename;
//首先查找文件目录中是否有这个文件
//如果有这个文件则记录在文件目录中的索引
    int pos = FindFile(filename);
//如果没有这个文件则插入不能完成
    if(pos == 0) {
        cout << "********不存在该文件,插入失败!********" << endl;
        return;
    }
//将这个块插入到文件的第 num 个位置
    int num;
    cout << "请输入要插入的文件逻辑位置:";
    cin >> num;
//判断是否有空间存储这个插入的块
    if(leftblocks == 0) {
        cout << "********无空闲块,插入失败!********" << endl;
        return;
    }
//找一个空闲的位置来存放要插入的块
    int p = 1;
    while(FAT[p] != 0)
        p++;
//如果要在第一个位置插入,则更新起始块号
    if(num == 1) {
        FAT[p] = start[pos];
        start[pos] = p;
    }
//不是在第一个位置插入
    else if(num >= 2) {
//找到要插入位置的前一个块号
        int temp = start[pos];
        for(int i = 1; i < num-1; i++)
            temp = FAT[temp];
//将新的位置的下一个索引指向原来的下一个块
        FAT[p] = FAT[temp];
//将上一个块的下一个索引指向新的位置,完成插入
        FAT[temp] = p;
    }
//更新剩余的内存块
    leftblocks--;
    cout << "********插入文件块成功!********" << endl;
}

//输出文件目录和 FAT
void info() {
    cout << "文件目录如下:" << endl;
    cout << "文件名\t 起始位置" << endl;
    for(int i = 1; i <= filenum; i++)
        cout <<"  "<< name[i] << "\t  " << start[i] << endl;
    cout << "文件定位表(FAT)如下:" << endl;
    cout << "索引\t内容" << endl;
    cout << "0\tFDF" << endl;
    cout << "1\tFFF" << endl;
    for(int i = 2; i < 32; i++)
        cout << i << "\t " << FAT[i] << endl;
}

//功能选择清单
void choicelist() {
    cout << "====================================================================" << endl;
    cout << "MS-DOS磁盘文件存储管理菜单:" << endl;
    cout << "1.向FAT中存储一个文件: " << endl;
    cout << "2.向FAT中的文件插入数据: " << endl;
    cout << "3.输出当前文件目录以及FAT信息: " << endl;
    cout << "4.结束操作,退出系统: " << endl;
    cout << "====================================================================" << endl;
}

int main() {
    init();
    int order;
//通过字符串输入来选择想要测试的功能
    choicelist();
    cout << "请输入你要执行的操作的编号: " ;
    while(cin >> order) {
//存 一个文件
        if(order == 1)
            save();
//在指定的文件中的特定位置插入一个块
        else if(order == 2)
            insert();
//显示当前的系统信息
        else if(order == 3)
            info();
//测试结束退出系统
        else if(order == 4) {
            cout << "系统结束" << endl;
            break;
        }
//输入指令不合法
        else
            cout << "指令输入错误" << endl;
        choicelist();
        cout << "请输入你要执行的操作的编号: " ;
    }
    return 0;
}

4、程序测试结果:
程序完成后随机选取数据进行测试,随机存入文件,然后插入块,检验结果是否正确,测试的初始值和结果如下图所示,根据检验,程序运行结果正确:
(1)存入文件
在这里插入图片描述
在这里插入图片描述
(2)插入块
在这里插入图片描述
在这里插入图片描述
(3)结束程序
在这里插入图片描述

(二)索引文件存储结构:

1、算法描述:
1)索引文件像链接文件一样,文件的逻辑记录信息可存放在非连续的磁盘存储空间中。但这些存放逻辑记录的存储空间不是按链表的形式链接在一起的,而是采用索引表来指出逻辑记录存放的物理位置。
文件目录与索引表的关系如下图所示:
在这里插入图片描述

2)建立索引文件的过程是:寻找一些空闲物理块;逻辑记录存入这些物理块中;把逻辑记录与物理块的对应关系登记在索引表中。

2、程序具体分析:
(1)程序中使用的数据结构及符号说明
算法的实现主要是依靠一些数组来完成,同时用一些变量进行辅助。算法中使用到的变量和数组的名称及其含义如下表所示:
变量名称 变量类型 变量含义
disk[] int* 物理磁盘块(0 未使用,1 已使用)
leftspace int 磁盘剩余空间
usercnt int 用户数量统计
user[] int* 用户存储列表
filecnt[] int* 每个用户的文件数量统计
blockcnt[][] int** 每个用户的每个文件的块数量
file[][] string** 每个用户的文件名称
filecata[][][] int*** 文件索引表
userpos int 某个用户在用户表中的索引
filepos int 某个文件在文件列表中的索引

(2)算法的具体步骤
首先通过键盘输入读取内存块的最大数量和想要测试的页面访问序列的长度,因为是序列的形式输入,所以为了避免歧义,规定所有的页面编号只在 0~9 范围内。接着初始化内存块的内容均为未使用,我们用-1 来表示尚未分配,同时将所有的页设置成不在内存中。
接着就开始序列的依次读取,每次读取一个序列的位,然后调用核心的 LRU 算法,判断是否发生缺页,同时对内存中的块内容进行修改,并统计缺页次数,操作完成以后输出是否缺页的计算结果,并输出操作完成以后当前内存的内容。读取完序列的所有内容,并统计完成缺页的次数,就可以计算缺页率,最后将缺页率和缺页次数输出即可。
首先这个算法当中比较重要的一部分就是这个保存内存内容的数组,为了方便每次的缺页替换,将这个数组设置成优先队列的形式,按照内存内容最后访问的时间先后进行排序,越靠前的内容最近被访问过,所以发生缺页的时候,如果需要替换,只要将排在最后的内容换出即可。
每次读取了序列的一位,表示需要访问的页号,就在内存当中寻找是否有这个页存在,由于采用了标记数组,所以直接查询即可知道是否在内存中。
如果需要的页在内存中,那么就不发生缺页,同时为了维持优先队列,由于刚刚访问了这个页,就需要在内存中找到这个页的位置,并逐个交换到队列的队首,表示最近一次访问过他,交换的时候不能改变其他的顺序,所以需要逐个交换到第一个。
如果不在内存中,那么就发生了缺页,就要将缺页的次数更新。这时候就要将这个页装入内存,分两种情况,如果内存已经满了,那么就把最后一个元素换成想要读取的页,然后把它逐个换到第一个位置上;如果内存没有满,那就先把他放到第一个空位上,更新内存中页的数量,然后把它交换到第一个位置上。放入内存并换到队首就完成了大部分的操作,然后标记这个页在内存中即可。最后输出内存中现在的内容即可继续读取下一个序列内容。

3、算法实现源代码:

//索引文件结构
#include <iostream>
using namespace std;
//磁盘物理块
//0 表示未被使用,1 表示已经被使用
bool disk[100001];
//磁盘剩余空间
int leftspace = 100000;
//用户数量统计
int usercnt = 0;
//用户存储列表
string user[101];
//每个用户的文件数量统计
int filecnt[101];
//文件块大小,用户 i 的第 j 个文件大小
int blockcnt[101][101];
//文件名称,用户 i 的第 j 个文件名
string file[101][101];
//文件索引表,用户 i 的文件 j 的第 k 块的物理地址
int filecata[101][101][101];

//初始化函数,重置磁盘和用户
void init() {
//所有磁盘标记为没有使用
    for(int i = 0; i < 100001; i++)
        disk[i] = 0;
//用户数量置位为 0
    usercnt = 0;
//输出提示信息
    cout << "********磁盘重置成功!********" << endl;
}

//搜索用户列表,判断用户是否已经存在
int finduser(string username) {
//在用户列表当中搜索同名的用户
    for(int i = 1; i <= usercnt; i++)
        if(user[i] == username)
            return i;
    return 0;
}

//搜索文件列表,判断文件是否已经存在
int findfile(string username, string filename) {
//在某个用户的文件列表中搜索是否有这个文件存在
    int usr = finduser(username);
    for(int i = 1; i <= filecnt[usr]; i++)
        if(file[usr][i] == filename)
            return i;
    return 0;
}

//创建新用户
void createuser() {
    string username;
    cout << "请输入用户名称:";
    cin >> username;
//判断是否已经存在同名的用户
    if(finduser(username) != 0) {
        cout << "********该用户已经存在,创建失败!********" << endl;
        return;
    }
//将这个用户存入用户列表
    user[++usercnt] = username;
//重置当前用户的文件数量
    filecnt[usercnt] = 0;
    cout << "********用户创建成功!********" << endl;
}

//添加新文件
void addfile() {
    string username;
    cout << "请输入要添加文件的用户名称: ";
    cin >> username;
//判断是否有这个用户
    if(finduser(username) == 0) {
        cout << "********没有这个用户,文件添加失败!********" << endl;
        return;
    }
    string filename;
    cout << "请输入要添加的文件的名称: ";
    cin >> filename;
//判断是否有同名的文件存在
    if(findfile(username, filename) != 0) {
        cout << "********已经存在同名文件,添加失败!********" << endl;
        return;
    }
    int len;
    cout << "请输入文件的长度: ";
    cin >> len;
//判断磁盘剩余空间是否够存储这个文件
    if(len > leftspace) {
        cout << "********文件长度过大,存储失败!********" << endl;
        return;
    }
//找到用户在用户列表中的位置
    int userpos = finduser(username);
//更新用户的文件数量
    filecnt[userpos]++;
//将文件加入到用户文件列表中
    file[userpos][filecnt[userpos]] = filename;
//更新这个文件占用的块数量
    blockcnt[userpos][filecnt[userpos]] = len;
    int pos = 0;
//占用磁盘资源
    for(int i = 1; i <= len; i++) {
//寻找一个空的磁盘块
        while(disk[pos] != 0)
            pos++;
//占用这个磁盘块
        disk[pos] = 1;
//记录映射关系
        filecata[userpos][filecnt[userpos]][i] = pos;
//更新剩余磁盘剩余块的数量
        leftspace--;
    }
//输出成功信息
    cout << "********文件存储成功!********" << endl;
}

//删除文件
void delfile() {
    string username;
    cout << "请输入要删除的文件所属的用户: ";
    cin >> username;
//寻找是否有这个用户
    if(finduser(username) == 0) {
        cout << "********没有这个用户,删除失败!********" << endl;
        return;
    }
    string filename;
    cout << "请输入要删除的文件名称: ";
    cin >> filename;
//寻找是否有要删除的文件
    if(findfile(username, filename) == 0) {
        cout << "********没有这个文件,删除失败!********" << endl;
        return;
    }
//记录用户在用户表中的位置
    int userpos = finduser(username);
//记录文件在文件表中的位置
    int filepos = findfile(username, filename);
//释放这个文件占用的磁盘资源
    for(int i = 1; i <= blockcnt[userpos][filepos]; i++) {
        disk[ filecata[userpos][filepos][i] ] = 0;
        leftspace++;
    }
//清空文件索引表中这个文件的记录
    for(int i = filepos; i < filecnt[userpos]; i++)
        for(int j = 1; j <= blockcnt[userpos][i+1]; j++)
            filecata[userpos][i][j] = filecata[userpos][i+1][j];
//清空这个文件的块数量记录
    for(int i = filepos; i < filecnt[userpos]; i++)
        blockcnt[userpos][i] = blockcnt[userpos][i+1];
//在文件目录中删除这个文件
    for(int i = filepos; i < filecnt[userpos]; i++)
        file[userpos][i] = file[userpos][i+1];
//文件数量减一
    filecnt[userpos]--;
    cout << "********文件删除成功!********" << endl;
}

//删除用户
void deluser() {
    string username;
    cout << "请输入要删除的用户名称: ";
    cin >> username;
    int userpos = finduser(username);
    if(userpos == 0) {
        cout << "********没有这个用户,删除失败!********" << endl;
        return;
    }
//释放这个用户占用的所有磁盘资源
    for(int i = 1; i <= filecnt[userpos]; i++) {
        for(int j = 1; j <= blockcnt[userpos][i]; j++) {
            disk[ filecata[userpos][i][j] ] = 0;
            leftspace++;
        }
    }
//删除这个用户所有文件索引记录
    for(int i = userpos; i < usercnt; i++)
        for(int j = 1; j <= filecnt[i+1]; j++)
            for(int k = 1; k <= blockcnt[i+1][j]; k++)
                filecata[i][j][k] = filecata[i+1][j][k];
//删除这个用户的文件目录
    for(int i = userpos; i < usercnt; i++)
        for(int j = 1; j <= filecnt[i+1]; j++)
            file[i][j] = file[i+1][j];
//删除这个用户的每个文件的文件块数量
    for(int i = userpos; i < usercnt; i++)
        for(int j = 1; j <= filecnt[i+1]; j++)
            blockcnt[i][j] = blockcnt[i+1][j];
//用户文件数量中删除这个用户的记录
    for(int i = userpos; i < usercnt; i++)
        filecnt[i] = filecnt[i+1];
//在用户列表里面删除这个用户的记录
    for(int i = userpos; i < usercnt; i++)
        user[i] = user[i+1];
//更新删除以后用户的数量
    usercnt--;
    cout << "********用户删除成功!********" << endl;
}

//输出当前信息
void showinfo() {
    cout << "当前用户的数量为: " << usercnt << endl;
    cout << "当前剩余的磁盘空间为: " << leftspace << endl;
    cout << "用户及文件信息如下:" << endl;
    for(int i = 1; i <= usercnt; i++) {
        cout << "\t**用户" << i << ": " << user[i] << endl;
        cout << "\t 文件数量:" << filecnt[i] << endl;
        cout << "\t 文件具体信息:" << endl;
        for(int j = 1; j <= filecnt[i]; j++) {
            cout << "\t\t*文件" << i << ": " << file[i][j] << "\t";
            cout << "占用的内存块: ";
            for(int k = 1; k <= blockcnt[i][j]; k++)
                cout << filecata[i][j][k] << " ";
            cout << endl;
        }
    }
}

//功能选择清单
void choicelist() {
    cout << "====================================================================" << endl;
    cout << "请输入你要执行的操作的编号:" << endl;
    cout << "0.结束操作,退出系统" << endl;
    cout << "1.重置磁盘" << endl;
    cout << "2.创建新用户" << endl;
    cout << "3.添加新文件" << endl;
    cout << "4.删除文件" << endl;
    cout << "5.删除用户" << endl;
    cout << "6.输出用户及文件信息" << endl;
    cout << "====================================================================" << endl;
}

int main() {
    int choice;
    choicelist();
        cout << "请输入你要执行的操作的编号: " ;
//根据选择的不同的功能来执行相应的操作
    while(cin >> choice) {
        switch (choice) {
//退出系统
            case 0:
                cout << "运行结束,系统退出" << endl;
                return 0;
                break;
//重置磁盘,全部置零
            case 1:
                init();
                break;
//创建新用户
            case 2:
                createuser();
                break;
//添加新文件
            case 3:
                addfile();
                break;
//删除文件
            case 4:
                delfile();
                break;
//删除用户
            case 5:
                deluser();
                break;
//输出当前信息
            case 6:
                showinfo();
                break;
//功能选择不正确,重新选择
            default:
                cout << "选择不正确,请重新选择" << endl;
        }
        choicelist();
            cout << "请输入你要执行的操作的编号: " ;
    }
    return 0;
}

4、算法测试结果:
程序完成后随机选取数据进行测试,创建两个用户并创建文件,然后进行删除文件和删除用户的操作,每次操作完成以后都输出当前信息来进行检验。测试的初始值和结果如下图所示,根据检验,程序运行结果正确:
(1)创建一个用户
在这里插入图片描述

(2)随机创建每个用户的文件
在这里插入图片描述
在这里插入图片描述

(3)删除用户文件
在这里插入图片描述

(4)删除一个用户
在这里插入图片描述

(三)思考题:

(1)链表文件结构和索引文件结构各自的优缺点是什么?
1)链式结构
优点:提高了磁盘空间利用率,不需要为每个文件预留物理块;有利于文件插入和删除;有利于文件动态扩充。
缺点:存取速度慢,不适于随机存取;当物理块间的连接指针出错时,数据丢失;
更多的寻道次数和寻道时间;链接指针占用一定的空间,降低了空间利用率。
2)索引结构
优点:不需要为每个文件预留物理块。.既能顺序存取,又能随机存取。.足了文件动态增长、插入删除的要求。
缺点:较多的寻道次数和寻道时间。索引表本身带来了系统开销。如:内外存空间,存取时间等。

(2)当文件较大时,使得索引表也较大,如果索引表的大小超过了一个物理块,如何进行索引表的存取?
如果索引表的大小超过了一个物理块,可以采用间接索引(多重索引)的方式来解决,也就是在索引表所指的物理块中存放的不是文件信息,而是装有这些信息的物理块地址,这样就对索引表的长度没有限制了,但是同时也会增加很多空间上的开销。如果是使用分页式管理位示图算法,文件存储的时候是按照块来分割的,内存的空间也是按照块来分割的,所以就一定是能够充分利用内存空间的,不会造成浪费。但是同时,这种算法实现起来复杂度较高,虽然寻找空闲块比较简单,但是文件的读取和存储都是分块进行的,而且位置之间没有顺序性,所以读取和存储的寻址和处理的时间代价很大,算法复杂度较高。另外,这种算法是需要页表来进行维系的,页表也需要存储,会造成空间的浪费,如果内存分块块比较小,数量很多,会导致页表非常大,极限情况下,内存会被页表完全占领,造成极大的浪费,效率受到影响。

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值