操作系统课程设计——文件管理系统(C语言版)

操作系统系列文章

http://t.csdnimg.cn/7XAnU

文章目录

实验一、进程的创建与撤销:http://t.csdnimg.cn/po4V0

实验二、银行家算法:http://t.csdnimg.cn/O5zoF


目录

操作系统系列文章

文章目录

文件管理

一、目的

二、设计内容

[三、 设计要求](#三、 设计要求)

四、设计思想

1、总体设计思想

[2、 结构体FCB](#2、 结构体FCB)

3、创建文件或目录

4、寻找空磁盘存文件

5、删除文件

五、源代码

六、运行结果

七、课设总结:


文件管理

一、目的

通过模拟磁盘,完成操作系统的文件管理功能,掌握包括目录结构的管理、外存空间的分配与释放以及空闲空间管理三部分。为写入模拟磁盘的数据文件建立目录,目录可以是单级文件目录、双级文件目录、树形结构目录。在目录中选择某个文件可以将其数据读入模拟内存。

二、设计 内容

1、通过初始化操作建立一个模拟磁盘,在模拟磁盘中保存目录和文件内容。创建该模拟磁盘时可创建初始的根目录内容、文件分配表。

2、文件目录项(可以采用FCB格式)应包括文件名、类型(目录 or文件)、创建日期、大小、第一个磁盘块块号。

3、目录管理需支持:

  • (1)新建目录:在目录中新建空目录;
  • (3)删除目录:删除空目录
  • (4)为文件建立目录项:一个文件创建成功后,为该文件创建目录项,并将文件和相关信息写入目录;
  • (5)删除文件:删除目录中某个文件,删除其在磁盘中的数据,并删除目录项。如果被删除文件已经读入内存应阻止删除,完成基本的文件保护。

三、 设计要求

1.不同的功能使用不同的函数实现(模块化),对每个函数的功能和调用接口要注释清楚。对程序其它部分也进行必要的注释。

2.对系统进行功能模块分析、画出总流程图和各模块流程图。

3.用户界面要求使用方便、简洁明了、美观大方、格式统一。所有功能可以反复使用,最好使用菜单。

4.通过命令行相应选项能直接进入某个相应菜单选项的功能模块。

5.所有程序需调试通过。

四、设计思想

1、总体设计思想

此文件管理系统主要分为两个模块,一是目录管理,二是文件管理。

具体的模块功能如下:

(1)目录管理:目录管理主要是对目录的操作,包括创建、删除、查看、修改目录名以及切换目录等。

  • 创建目录:在当前目录下新建空目录,新件目录名不能与同级目录重名,但不同级目录可以重名。
  • 删除目录:在当前目录下删除空目录,如果不是空目录不可以删除。
  • 查看当前目录下的信息:可以查看当前目录的下的目录和文件,展现其相关信息,如名称、类型、创建时间、文件大小等。
  • 修改目录名:在当前目录下可修改目录名称,同理修改后的名称不能与同级目录重名。
  • 切换目录:在当前目录下可切换到上一级目录和下一级目录中。

****(2)文件管理:****主要是对文件的操作,包括创建、删除、修改文件名、打开、关闭文件以及查看FAT表和位示图等。

  • 创建文件:在当前目录下创建文件,在创建时需要输入名称、文件大小。
  • 删除文件:在当前目录下删除文件,当文件是打开状态则不能删除,必须先将其关闭后才能成功删除文件。
  • 修改文件名:在当前目录下可修改文件名称,同理修改后的名称不能与同级目录下的重名。
  • 查看FAT和位示图:查看文件分配表,即文件具体存储的盘块的位置,查看位示图,即当前盘块的状态。

2、 结构体FCB

该文件管理系统设计了一个文件目录项,采用FCB格式,其中包括文件名、类型(目录or文件)、创建时间、大小、第一个盘块号。其中存储目录或文件采用二叉树的模式。FCB结构体定义如下:

cpp 复制代码
typedef struct FCB
{                       //文件或目录控制块
    char name[10];      //文件或目录名
    int size;           //文件或目录大小,目录大小可设置为 0
    char type;          //类型,1 为文件,2 为目录
    int first;          //外存起始位置  -1被占 -2未被占
    char datetime[128]; //日期时间,格式为 yyyymmdd hhmmss
    struct FCB *next;   //下一个兄弟节点,相同父结点的节点称为兄弟结点
    struct FCB *child;  //第一个孩子节点
    struct FCB *parent; //父节点
    int read = 0;       //是否打开,1为打开,0为关闭

} F;

3、创建文件或目录

4、寻找空磁盘存文件

当新建文件时,需要根据文件大小为其分配磁盘空间存储文件。该功能主要是通过findNULL()函数实现的,主要思想如下:

首先,通过文件大小f_size计算需要多少个盘块F_SIZE,需要使用向上取整的方式计算,已经规定每个盘块大小为10B,计算方法如下:F_SIZE=(f_size - 1)/10然后利用for循环遍历b[][]位示图数组,找到空闲盘块,将其转换为盘块号 x=i*8+j,并将盘块号x存放在临时数组m[100]中,并修改位示图,b[i][j]=1(为1表示占用,0表示未占用),跳出本次循环,然后在进行第二次循环寻找第2个可用盘块,直到k=F_SIZE,结束最外层循环,已经全部找到可用盘块位置。

其次 ,当盘块号全部找到后修改FAT表(-2表示未被占用,-1表示已用,大于0 的数表示磁盘号),FAT表是一个索引表,FAT[i]表示下一个盘块号,i表示该文件的第一个盘块号。

5、删除文件

定义全局结构体变量p,指向当前目录,定一个局部结构体变量np,并使np=p。删除文件首先要输入删除文件或目录名name,然后遍历二叉树找到该目录的前一个结点,即np->next->name=name,然后判断np->next是的类型是否为文件,如果是将其删除,并调用updateTable()更新FAT表和位示图。如果都遍历完没有找到,提示用户该文件不存在!

6、切换目录

定义全局结构体变量p,指向当前目录,定一个局部结构体变量np,并使np=p,在使得np指向其孩子结点。利用while循环遍历二叉树,寻找到np->name=name, 找到后将np赋给p,使得p指向np.当np==NULL ,提示用户未找到该文件或目录。最后调用updatelujing()函数显示当前路径。

五、源代码

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
/*
先假设内存大小为64kb,块大小为1K,一个文件或目录最多可以用3个盘块存储
1、先建立位示图,利用随机函数生成*/
// 1为目录,2为文件
void menu();               //菜单
void initdir();            //初始化根目录
void byteCreat();          //创建位示图
void updatelujing();       //更新当前光标所在位置(就是路径)
int updateTable(int, int); //当文件删除时,修改FAT表和修改位示图
int findNULL();            //寻找空位置
void getTime();            //获取时间

void create_Dir(int); //创建目录或者文件
void delDir(char *);  //删除空目录
void printNow();      //显示当前目录下的文件或目录
void delFile(char *); //删除文件
void cdir(char *);    //切换下一级
void byteShow();      //显示位示图
void fatShow();       //显示FATm
void openfile(char);  //打开文件
void closefile(char); //关闭文件

typedef struct FCB
{                       //文件或目录控制块
    char name[10];      //文件或目录名
    int size;           //文件或目录大小,目录大小可设置为 0
    char type;          //类型,1 为文件,2 为目录
    int first;          //外存起始位置  -1被占 -2未被占
    char datetime[128]; //日期时间,格式为 yyyymmdd hhmmss
    struct FCB *next;   //下一个兄弟节点,相同父结点的节点称为兄弟结点
    struct FCB *child;  //第一个孩子节点
    struct FCB *parent; //父节点
    int read = 0;       //是否打开,1为打开,0为关闭

} F;

int COUNT = 0; //文件个数
int F_SIZE;    //一个文件可以占几个盘块
// int F_SIZE_LIST[50]; //每个文件的盘块个数

F *p = NULL;     //全局变量,指向当前目录
int b[100][100]; //位示图数组
int FAT[100];    //文件分配表
// node *head = NULL; //全局变量,?

// 1、获取当前创建时间,利用time函数
void getTime(FCB *f)
{
    time_t t; //时间对象变量
    char buf[128];
    memset(buf, 0, sizeof(buf)); //清空数组

    struct tm *tmp; //时间结构体
    t = time(NULL);
    tmp = localtime(&t);
    strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tmp);

    for (int i = 0; i < 128; i++) //存时间
    {
        f->datetime[i] = buf[i];
    }
}
//创建位示图
void byteCreat()
{
    srand((unsigned)time(NULL));
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            b[i][j] = rand() % 2; //随机生成位示图 0表未用,1表已用

            printf("%d ", b[i][j]); //打印出来

            //修改一下把-2表示未用
            if (b[i][j] == 0)
            {
                FAT[i * 8 + j] = -2; //未被占;
            }
            else if (b[i][j] == 1)
            {
                FAT[i * 8 + j] = -1; //-1:被占
            }
        }
        printf("\n");
    }

    printf("\n***FAT表的初始值如下:\n");
    printf("\n");
    for (int i = 0; i < 64; i++)
    {

        printf("%3d ", FAT[i]);
        if (i != 0 && ((i + 1) % 8 == 0))
        {
            printf("\n");
        }
    }
    printf("\n");
}
// 2、寻找空位置
int findNULL()
{
    int a = 0; //哨兵
    int x;     //转化为盘块号
    int m[100];
    for (int k = 0; k < F_SIZE; k++)
    {
        a = 0;
        for (int i = 0; i < 8; i++) //第一行0,一趟就找一个0,而且是最先出现的0.
        {
            for (int j = 0; j < 8; j++)
            {
                if (b[i][j] == 0)
                {
                    x = i * 8 + j; //转化为盘块号
                    m[k] = x;      //存入第一个盘块位置
                    b[i][j] = 1;
                    a = 1;
                    break;
                }
            }
            if (a == 1)
                break; //跳出第二层循环
        }
    }

    printf("\n\n-------找到的盘块位置如下------\n\n");
    for (int k = 0; k < F_SIZE; k++)
    {
        printf("%d,", m[k]);
    }

    //创建FAT表
    for (int k = 0; k < F_SIZE; k++)
    {
        int y = 0;
        y = m[k];          //当k=0时,把第一个盘块号给Y,
        FAT[y] = m[k + 1]; //第盘块Y号指向下一个盘块号,所以FAT[y]的值代表下一个盘块号位置
        printf("\nFAT[y]下一个盘块是:%d\n", FAT[y]);
        //最后一个没有下一个盘块位置
        if (k == F_SIZE - 1)
        {
            FAT[y] = -1; //外存起始位置  -1被占 -2未被占,最后一个没有下一个盘块位置
            printf("\nFAT[y]下一个盘块是:%d\n", FAT[y]);
        }
        //最后一个没有下一个盘块位置
    }
    return m[0];
}

// 3、创建目录
void create_Dir(int a)
{
    char name[10];
    F *np = p;
    printf("请输入目录或文件的名字\n");
    scanf(" %s", name);

    F *f = (F *)malloc(sizeof(F)); //新建空白目录
    strcpy(f->name, name);
    //赋值
    //-------创文件--------
    if (a == 1) // ,1表示文件
    {
        int f_size;
        printf("\n请输入文件大小(单位B):");
        scanf("%d", &f_size);
        f->size = f_size;
        F_SIZE = (f_size - 1) / 10; //向下取整,算个需要多少盘块
        f->read = 0;
        // F_SIZE_LIST[COUNT] = F_SIZE; //将这个文件需要的盘块数存入数组中
        COUNT++;               //文件数加一
        f->type = 1;           //写入类型
        f->first = findNULL(); //找空位置,返回x,x是第一个磁盘号(位置)
        printf("\n----找到的起始位置是:%d\n\n", f->first);
    }

    //----------创目录---------
    if (a == 2) // 2表示目录
    {
        f->type = 2;
        f->first = -2;
        f->size = 0;
    }
    getTime(f);
    f->child = NULL;
    f->next = NULL;
    f->parent = np; // np当前目录
    if (np->child == NULL)
    {
        np->child = f;
    }
    //当前使用用的是链表进行存储文件的,映射成一棵树,
    //在当前目录创建,需要找到一个结点,该结点的兄弟结点为空时,插入,就是在最后插入
    else //进入当前子目录
    {
        np = np->child; //指向第一个目录或文件,假设为F1
        if (a == 2)
        {
            if (np->type == 2) //目录
            {
                //有两个情况,1是建在目录和文件,2是建在目录与目录中(正常情况)
                while (np->next != NULL) //指当前F1的兄弟结点不为空
                {
                    if (np->type == 2 && np->next->type == 1) //新建在目录和文件中间
                    {
                        break;
                    }
                    np = np->next; //指向下一个,继续找兄弟节点直到找到没有兄弟结点的位置,也就是末尾。
                }
                //没有兄弟节点位置,末尾插入,
                f->next = np->next;
                np->next = f;
            }
        }

        else if (a == 1) //文件的,同理
        {
            while (np->next != NULL)
            {
                np = np->next;
            }
            f->next = np->next;
            np->next = f;
        }
    }
}

// 4、更新当前光标所在位置(就是路径)
void updatelujing() //更新当前光标所在位置(就是路径)
{
    F *np = p;     //将np指向当前目录 ,FCB
    F a[100];      //临时存储文件或目录信息结构体数组
    int count = 0; // 局部变量??

    while (np->parent != NULL) //如果父结点不为空,第一次未创建文件或目录时不会执行
    {
        a[count] = *np;  //将当前信息存入数组a中
        np = np->parent; // np从当前位置一直往上找父节点,直到根目录就结束
        count++;         //???
    }
    //输出当前目录前的路径,除了它本身,这样是为了可以输出root\>
    for (int i = count - 1; i > 0; i--)
    {
        printf("%s\\", a[i].name);
    }

    //输出当前目录的名字。
    printf("%s\\", p->name); // p是当前目录,没有创建目录时,p->name为root
    printf(">");             //最后打印出来就是 root\>
}

//初始化根目录
void initdir()
{
    F *f = (F *)malloc(sizeof(F)); //开辟一个FCB,根目录
    //初始化根目录 独立出来
    strcpy(f->name, "root");
    f->type = 2;      // 2表目录
    f->size = 0;      //大小为0
    getTime(f);       //获取创建时的时间
    f->child = NULL;  //孩子结点为空
    f->next = NULL;   //下一个兄弟节点
    f->parent = NULL; //父节点
    f->first = -2;
    p = f; // p指向当前目录,p指向根目录
}

void delDir(char *name) //删除空目录,删除当前目录的一级子目录,且为空目录
{
    int flag = 0;
    F *np = p;
    if (np->child == NULL) //当前目录下的
        printf("无此目录\n");
    else
    {
        np = np->child;
        if (strcmp(np->name, name) == 0 && np->child == NULL) //为第一个,当前的子目录
        {
            p->child = np->next;
            free(np);
            printf("成功删除此目录\n");
            flag = 1;
        }
        else
        {
            while (np->next != NULL) //找到要删除的前一个并且为空文件夹
            {
                if (strcmp(np->next->name, name) == 0 && np->next->child == NULL)
                {
                    np->next = np->next->next; //把当前np的兄弟结点指向要删除的兄弟结点,后一个目录往前移
                    flag = 1;
                    printf("成功删除此目录\n");
                    break;
                }
                np = np->next;
            }
        }
        if (flag == 0)
        {
            printf("删除失败!无当前目录或当前目录不为空\n");
        }
    }
}

//输出当前目录下的文件或目录
void printNow()
{
    F *np = p;
    if (p->child == NULL)
    {
        printf("当前文件夹为空\n");
    }
    else
    {
        np = np->child;
        // printf("%s    <DIR>      .\n", np->parent->datetime);
        printf("%s    <DIR>      ..\n", np->parent->datetime);
        while (np != NULL)
        {
            printf("%s 类型:%d 名字:%s\n", np->datetime, np->type, np->name);
            np = np->next;
        }
    }
}

//删除文件
void delFile(char *name)
{
    int flag = 0;
    F *np = p;
    if (np->child == NULL)
        printf("无此文件\n");
    else
    {
        np = np->child;
        if (strcmp(np->name, name) == 0) //为第一个
        {
            if (np->read == 0)
            {
                printf("\n文件状态%d \n", np->read);
                p->child = np->next;
                printf("\n成功删除此文件\n");
                updateTable(np->first, np->size); //更新fat表
                flag = 1;
            }
            else
            {
                printf("\n文件状态%d \n", np->read);
                flag = 1;
                printf("\n文件已经打开,请关闭再删除!\n");
                printf("删除失败!\n\n");
            }
        }
        else
        {
            while (np->next != NULL)
            {
                if (strcmp(np->next->name, name) == 0) //找到前一个,要删除的
                {
                    if (np->next->read == 0)
                    {
                        printf("\n文件状态%d \n", np->next->read);
                        updateTable(np->next->first, np->next->size); //更新fat表
                        np->next = np->next->next;
                        flag = 1;
                        printf("成功删除此文件\n");
                        break;
                    }
                    else
                    {
                        printf("\n文件状态%d \n", np->next->read);
                        flag = 1;
                        printf("\n文件已经打开,请关闭再删除!\n");
                        printf("删除失败!\n\n");
                    }
                }
                np = np->next;
            }
        }
        if (flag == 0)
        {
            printf("删除失败!无当前目录或当前目录不为空\n");
        }
    }
}

//更新FAT表和位示图
int updateTable(int first, int size) //更新FAT表
{

    int next = first; // 第一个盘号
    int p_count = (size - 1) / 10;
    int m[50]; //临时数组,存该文件的每个盘块号
    //m[0] = next;
    int count = 0;
    //找到所有盘块号,存入m
    int i = next;
    while (1)
    {
        // if (FAT[i] != -2 && FAT[i] != -1) //不为-2

        int j = FAT[i];
        m[count] = i;
        count++;
        i = j;
        if (j == -1)
        {
            break;
        }
    }
    //修改FAT
    for (int i = 0; i < p_count; i++)
    {
        FAT[m[i]] = -2;
    }

    //修改位示图
    for (int i = 0; i < p_count; i++)
    {
        b[m[i] / 8][m[i] % 8] = 0;
    }
    return 0;
}

//
void cdir(char *name) //切换目录下一个目录
{
    F *np = p;
    np = np->child;                  //让np指向当前目录的孩子结点(下一级目录或文件)
    if (strcmp(np->name, name) == 0) //判断两个是否相等
    {
        p = np; //找到并进入,当前目录p就为np
    }
    else
    {
        while (strcmp(np->name, name) != 0)
        {                                    //不等于,就找下一个
            np = np->next;                   //找其
            if (strcmp(np->name, name) == 0) //找到就进入
            {
                p = np; //找到并进入
                break;
            }
            if (np == NULL) //全部遍历完,都没有找到
            {
                printf("未找到此目录");
                break;
            }
        }
    }
}

//显示位示图
void byteShow()
{
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            printf("%d ", b[i][j]);
        }
        printf("\n");
    }
}

void fatShow() //文件配置表
{
    printf("\n");
    printf("\n-------FAT表如下:\n");
    for (int i = 0; i < 64; i++)
    {

        printf("%3d ", FAT[i]);
        if (i != 0 && ((i + 1) % 8 == 0))
        {
            printf("\n");
        }
    }
    printf("\n");
}

void openfile(char *name) //打开文件
{
    F *np = p;
    np = np->child;                  //让np指向当前目录的孩子结点(下一级目录或文件)
    if (strcmp(np->name, name) == 0) //判断两个是否相等
    {
        np->read = 1; //标记状态已读
    }
    else
    {
        while (strcmp(np->name, name) != 0)
        {                                    //不等于,就找下一个
            np = np->next;                   //找其
            if (strcmp(np->name, name) == 0) //找到就进入
            {
                // p = np; //找到并进入
                np->read = 1; //标记状态已打开
                printf("\n文件已经打开!\n");
                break;
            }
            if (np == NULL) //全部遍历完,都没有找到
            {
                printf("未找到此目录");
                break;
            }
        }
    }
}

void closefile(char *name) //关闭文件
{
    F *np = p;
    np = np->child;                                   //让np指向当前目录的孩子结点(下一级目录或文件)
    if (strcmp(np->name, name) == 0 && np->type == 1) //判断两个是否相等,且为文件
    {
        np->read = 0; //标记状态已读
    }
    else
    {
        while (strcmp(np->name, name) != 0)
        {                                                     //不等于,就找下一个
            np = np->next;                                    //找其
            if (strcmp(np->name, name) == 0 && np->type == 1) //找到就进入
            {
                // p = np; //找到并进入
                np->read = 0; //标记状态已关闭
                printf("\n文件已经关闭!\n");
                break;
            }
            if (np == NULL) //全部遍历完,都没有找到
            {
                printf("未找到此目录");
                break;
            }
        }
    }
}

//菜单
void menu()
{

    char choise[10];
    char f_name[10];
    int flag = 1;
    while (flag)
    {
        printf("\n*************文件系统***************************\n");
        printf("             1.md(创建目录)\n");
        printf("             2.rd(删除目录)\n");
        printf("             3.dir(列出当前目录下信息)\n");
        printf("             4.mk(创建文件)\n");
        printf("             5.del(删除文件)\n");
        printf("             6.cd(切换目录)\n");
        printf("             7.cd..(返回上一级)\n");
        printf("             8.fat(展示文件分配表FAT)\n");
        printf("             9.show(展现位示图)\n");
        printf("             10.open(打开文件)\n");
        printf("             11.close(关闭文件)\n");
        printf("*************************************************\n\n");
        do
        {
            //更新当前所在(当前所在路径)*
            updatelujing();
            scanf("%s", &choise);

            //创建目录*
            if (strcmp(choise, "md") == 0)
            {
                create_Dir(2); // 2为目录,1为文件
            }
            //删除空目录*
            else if (strcmp(choise, "rd") == 0)
            {
                //printf("请输入需要删除的文件名\n");
                scanf("%s", f_name);
                delDir(f_name);
            }
            //显示当前目录下目录或文件*
            else if (strcmp(choise, "dir") == 0) //
            {
                printNow();
            }
            //创建文件*
            else if (strcmp(choise, "mk") == 0)
            {
                create_Dir(1); // 1为文件
            }
            //删除文件*
            else if (strcmp(choise, "del") == 0)
            {
                //printf("请输入需要删除的文件名\n");
                scanf("%s", f_name);
                delFile(f_name); //删除文件
            }
            //切换下一级目录*
            else if (strcmp(choise, "cd") == 0)
            {
                //printf("请输入目录名\n");
                scanf(" %s", f_name);
                cdir(f_name);
            }
            //切换上一级*
            else if (strcmp(choise, "cd..") == 0)
            {
                p = p->parent; //直接让当前目录的指针指向父节点。
            }
            //展示FAT*
            else if (strcmp(choise, "fat") == 0)
            {
                fatShow();
            }
            //展示位示图*
            else if (strcmp(choise, "show") == 0)
            {
                byteShow();
            }
            else if (strcmp(choise, "open") == 0) //读文件
            {
                //printf("请输入需要读的文件名\n");
                scanf("%s", f_name);
                openfile(f_name);
            }
            else if (strcmp(choise, "close") == 0) //写文件
            {
                //printf("请输入需要关闭的文件名\n");
                scanf("%s", f_name);
                closefile(f_name);
            }

        } while (flag == 1);
    }
}

int main()
{

    printf("\n------初始化根目录中...\n");
    initdir(); //初始化根目录
    printf("****初始化位示图\n");
    byteCreat(); //创建位示图
    menu();      //菜单
    return 0;
}

六、运行结果

1、进入系统初始界面

2、测试数据

(1)创建目录

测试在根目录root下创建两个子目录11和22,在子目录11中在创建子目录111。结果如下:

(2)删除空目录

测试删除目录,删除目录11,和目录222,只有空目录才能删除。测试结果如下:

(3)切换目录

(4)创建文件

  1. 在根目录下创建qq.txt 文件,大小为32B测试结果如下:
  1. 在11目录下新建文件ww.txt 大小为21B,测试结果如下:

(5)删除文件

测试在11目录下删除已打开的ww.txt文件,文件打开状态不能删除文件,关闭后才能删除。测试结果如下:

(6)打开文件

打开ww.txt文件,测试结果如下:

(7)关闭文件

关闭qq.txt文件,测试结果如下:

七、 课设总结:

本次课程设计的选题是文件管理,在此次课程设计中收获颇多。不仅加深了对操作系统这门课程的理解,通过实操还将课本上的知识、对文件管理所涉及的思想应用到实际的开发上。在此次设计过程中也遇到了一些问题及其解决方案如下:

(1)最开始新建文件时,是固定了每个文件只能占3个盘块,后来发现这是一个可以改进的缺陷,于是在FCB结构体中在定义了一个代表文件大小的属性size,然后模拟的一个磁盘大小是10B,一共64个磁盘。通过对向上取整根据每个文件大小计算需要多少个盘块,即F_SIZE=(size-1) /10.这样就得到F_SIZE每个文件所需的盘块数。最后利用三重for循环将所需的盘块,每次找到一个空闲磁盘块就结束,寻找第二个时从头开始找。找到并存入临时数组m[100]中。其中在查找空闲磁盘块中也是存在缺陷的,时间复杂度较高。还有改进的空间,可改成找到所有所需的磁盘块在结束,即寻找第二个盘块就无需从头开始。

(2)在新建文件后更改FAT表时也存在一些缺陷。原先设计的FAT表中如果FAT[i]为大于0的数就是代表盘块号,在后续的开发中发现,当需要寻找每个文件存储在哪个盘块时比较麻烦,后来回归课本,发现可以使用索引的方式可以快速的、准确的找到每个文件所占用的盘块号,即FAT[i]表示下一个盘块号,i表示文件的第一个盘块号。

(3)在删除文件后需要更改FAT表及位示图中也遇到一些麻烦。因为FAT[i]表示的含义下一个盘块号,就无法使用简单的遍历FAT表找到就将其修改。因为这个问题想了很久,最终找到了解决方法,具体实现是这样的,先取出该文件的一个盘块号first和文件大小,计算该文件需要多少个盘块记为F_SIZE,利用while循环在循环中定义一个变量j,存FAT[i]的值,即索引的下一个盘块号,i=first即最开始为第一个盘块号,先将i存储在临时数组m[ ]中,然后使i=j,继续进入下一次循环,直到j=-1,( 即FAT[i]=-1表示最后一个磁盘没有索引号了 ),故结束循环.最后利用m数组修改FAT和位示图。


相关推荐
MessiGo30 分钟前
Javascript 编程基础(5)面向对象 | 5.2、原型系统
开发语言·javascript·原型模式
慢半拍iii1 小时前
数据结构——D/串
c语言·开发语言·数据结构·c++
怀旧,1 小时前
【数据结构】5. 双向链表
数据结构·windows·链表
拄杖忙学轻声码2 小时前
windows电脑解决笔记本搜索不到wifi问题
windows·电脑
waterHBO2 小时前
Cursor 编辑器, 使用技巧,简单记录一下
windows·编辑器
爱学习的白杨树2 小时前
Sentinel介绍
java·开发语言
Frankabcdefgh2 小时前
Python基础数据类型与运算符全面解析
开发语言·数据结构·python·面试
kaiaaaa2 小时前
算法训练第十五天
开发语言·python·算法
笑鸿的学习笔记3 小时前
Windows笔记之Win11让非焦点窗口程序也能获得流畅性能的方法
windows·笔记
whoarethenext3 小时前
使用 C/C++ 和 OpenCV 提取图像的感兴趣区域 (ROI)
c语言·c++·opencv