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

[实验目的] 通过一个简单的基于位示图的文件存储空间管理模拟算法的设计,加深理解文件系统的外存分配管理原理。

[实验学时] 4 学时

[实验类型] 综合性

[实验内容]

设计一个 m 行 n 列(自定)二维数组表示位示图结构,利用初始化操作模拟给出位示图的原始状态或者某一时刻的当前状态,设计算法:

1)完成给某文件分配几个盘块的过程(返回分配的盘块号并修改位示图); 2)完成某磁盘块的回收过程(根据要回收的盘块号求解出对应位示图位置并修改位示图)。

注意:

  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;       /* 总文件数 */
int     blockSize = 1;          /* 磁盘块大小 */

/*
* *函数名: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 循环 */
            }else
                x = 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" );
    }
}

/*
* *函数名:allocationDiscrete(int fileNum)
* *描述: 分配空间给文件,采用离散分配方式
* *参数: fileNum  第几个文件
* *返回值: 无
**/
void allocationDiscrete(int fileNum)
{
    int length = File[fileNum].length;
    int b[60];
    int i, j;
    int x = 0;
    for (i = 0; i < length; i++)
    {
        for (j = 0; j < line; j++)
        {
            if (map[j][i] == 0)
            {
                b[x] = j * column + i;
                x++;
                if (x == length)
                    break;
            }
            else
                x = 0;
        }
        if (x == length)
            break;
    }
    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;
        }
    }
    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 );

    if (blockSize == 1)
        allocationDiscrete(fileTotalNum);
    else
        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" );
    else
        for ( 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;
    printf("请选择磁盘块的大小(1:离散分配,其他:连续分配):");
    scanf("%d", &blockSize);
    mapInit();
    while ( 1 )
    {
        page();
        scanf( "%d", &mode );
        switch ( mode )
        {
            case 1:   allocInit(); break;
            case 2:   recoverInit(); break;
            case 3:   showDir(); break;
            default: printf( "不存在该操作,请重新输入\n" ); break;
        }
    }
}

原文地址: https://www.cveoy.top/t/topic/owIh 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录