文件系统:树形结构目录+多用户单进程文件系统实现

8 篇文章 0 订阅 ¥99.00 ¥99.00

原题:实验四  文件系统---设计测试实验

1.设计一个树形目录结构的文件系统,其根目录为root,各分支可以是目录,也可以是文件,最后的叶子都是文件。为该文件系统设计2~3个文件操作命令,并加以实现。如显示树形目录的命令、移动读写指针命令、改变文件属性命令、更换文件名命令、改变文件保护级别命令等。

要求:

1)描述系统模型、命令功能设计流程,定义数据结构。

开始运行程序会自动创建根目录root,用户可以选择在root下添加目录或文件,也可以在自己选的子目录下添加目录和文件,程序提供查看所有文件位置的功能(按树形结构打印输出所有目录下的文件名)。要实现树形文件结构,需要定义结构体表示树的结点,结点有2个指针,一个指向子结点,一个指向兄弟结点(即和该结点属于同一个父节点的结点),我给它们分别起名为child、brother。为了更直观的说明,举个例子:

各结点间逻辑关系:

对应数据结构直观示意:

对于树形结构结点的各种操作,都基于对树的遍历,在指定结点下添加子结点需要遍历树找到该结点,展示所有结点之间关系需要遍历整棵树并按格式打印,用深搜可以实现对树的遍历。如果当前结点是文件,下一个访问的结点是该结点brother所指向的结点;如果当前结点是目录,下一个访问的结点是该结点的子结点。

2)写代码(含完整注释)并运行调试。

3)实验报告中包含运行的数据和结果。

4)提交材料包括:源代码、可运行文件、软件文档和实验报告。

我为文件系统设计的操作命令为添加目录(文件)、查看所有文件(按树形结构)。设计代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define getpch(type) (type *)malloc(sizeof(type))

char s[50];
char t[50];
char tip[2][16] = { "目录","文件" };
int find;

struct node
{
    char fileName[50];
    char content[200];
    int flag;//0表示目录,1表示文件
    struct node* child, * brother;
}*head, * p;
typedef struct node File;

void init()//初始化建立一个根目录root
{
    head = getpch(File);
    strcpy(head->fileName, "root");
    head->child = head->brother = NULL;
    head->flag = 0;
}

void search(File* temp)//搜索目录
{
    while (temp != NULL)
    {
        if (find) break;//找到目标目录则退出

        strcpy(t, temp->fileName);//读取当前目录
        if (strcmp(s ,t) == 0 &&
        !temp->flag)//找到目标目录
        {
            p = temp;
            find = 1;
            return;
        }
        else if (!temp->flag) {//搜索子目录
            search(temp->child);
            if (find) break;//找到目标目录则退出
        }

        temp = temp->brother;
    }

    return;
}

void insertItem(int flag)//插入目录或文件
{
    printf("\n请输入该%s所在目录:",tip[flag]);
    scanf("%s", s );
    File* temp = head;
    p = NULL;
    find = 0;
    search(temp);
    if (p == NULL) {
        printf("\n找不到该目录!");
        return;
    }

    File* t = getpch(File);
    printf("\n请输入该%s名称:",tip[flag]);
    scanf("%s", s , sizeof(s));
    strcpy(t->fileName, s);
    if (flag) {
        printf("\n请输入该%s内容:\n",tip[flag]);
        scanf("%s", s);
        strcpy(t->content, s);
    }
    t->flag = flag;
    t->brother = t->child = NULL;
    if (p->child == NULL)//将子项插入到目录中
    {
        p->child = t;
    }
    else
    {
        File* first, * second;
        first = p->child;
        second = first->brother;
        while (second != NULL)
        {
            first = second;
            second = second->brother;
        }
        first->brother = t;
    }
}

void display(int n, File* p)//以树形结构显示所有文件
{
    printf("\n");//首先打印目录
    for (int i = 0; i < n; i++)
    {
        printf(" ");
    }
    printf("%s", p->fileName);

    if (p->child != NULL)//然后打印目录子项
    {
        p = p->child;
        while (p != NULL)
        {
            if (!p->flag) {//读取子目录
                display(n + 1, p);
            }

            else {
                printf("\n");
                for (int i = 0; i < n + 1; i++)
                {
                    printf(" ");
                }
                printf("%s", p->fileName);
            }

            p = p->brother;
        }
    }

    return;
}

void menu()
{
    int i, j;
    printf("\n\n**********树形结构目录文件系统**********");
    printf("\n选择操作:\n-----1.插入目录\n"
           "-----2.插入文件\n"
           "-----3.查看所有文件\n-----0.退出程序");
    printf("\n请选择:");
    scanf("%d", &i);
    if (i == 1)
    {
        insertItem(0);
    }
    else if (i == 2)
    {
        insertItem(1);
    }
    else if (i == 3)
    {
        p = head;
        display(0, p);
    }
    else if (i == 0)
    {
        exit(0);
    }
    else printf("\n没有该选项!");
}
int main()
{
    init();
    while (1)
    {
        menu();
    }
    return 0;
}

2.设计一个容纳n个用户的文件系统,每个用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有create、delete、open、close、read、write命令。

要求:

1)描述系统模型、命令功能设计流程,定义数据结构。

本程序使用基于上题代码的树形结构,不过为了减少代码量,我在这个程序没有提供添加子目录的功能,创建一个用户就自动创建一个根目录,用户只能在该根目录下创建文件。本程序提供的功能有创建文件(对应Create和write)、删除文件(对应delete)、打开文件(对应open和read)、修改文件(对应open和write,只读文件无法使用此功能)、关闭文件(对应close),以及查看文件(按树形结构输出用户所有文件名)和创建用户。

2)写代码(含完整注释)并运行调试。

3)实验报告中包含运行的数据和结果。

4)提交材料包括:源代码、可运行文件、软件文档和实验报告。

设计代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define getpch(type) (type *)malloc(sizeof(type))
#define N 2 //最多2个用户
#define M 2 //每个用户最多4个作业

char s[64];
char t[64];
char file[4][64];//[N*M][*]
int find;
int num[2] = {0,0};//[N],初始时用户文件为0
int sum = 0;//初始时文件数为0

struct node
{
    char fileName[32];
    char *content;
    int flag;//0表示目录,1表示文件
    int limit;//0表示无限制,1表示只读
    struct node* child, * brother;
}*head[2]/*[N]*/, * p , * open;
typedef struct node File;

void init(int user)//为用户建立一个根目录
{
    head[user] = getpch(File);
    printf("\n请输入用户名:");
    scanf_s("%s", head[user]->fileName, sizeof(s));
    head[user]->child = NULL;
    head[user]->brother = NULL;
    head[user]->flag = 0;
    head[user]->limit = 0;
    head[user]->content = NULL;
}

void search(File* temp)//搜索文件
{
    while (temp != NULL)
    {
        if (find) break;
        
        strcpy_s(t, temp->fileName);
        if (strcmp(s ,t) == 0 && temp->flag)
        {
            p = temp;
            find = 1;
            return;
        }
        else if (!temp->flag) {
            search(temp->child);
            if (find) break;
        }

        temp = temp->brother;
    }

    return;
}

void insertItem(int user)//插入文件
{
    ++num[user];
    ++sum;

    File* t = getpch(File);

    printf("\n请输入该文件名称:");
    scanf_s("%s", s , sizeof(s));
    strcpy_s(t->fileName, s);

    int pos;
    for (pos = 0; pos < N * M; ++pos)
    {
        if (file[pos][0]==' ') {
            break;
        }
    }
    t->content = file[pos];
    printf("\n请输入该文件内容:\n");
    scanf_s("%s", t->content , sizeof(s));

    printf("\n是否是只读文件?");
    printf("\n-----1.是");
    printf("\n-----0.否");
    printf("\n请选择:");
    scanf_s("%d", &t->limit);

    t->flag = 1;

    t->brother = NULL;
    t->child = NULL;
    if (head[user]->child == NULL)
    {
        head[user]->child = t;
    }
    else
    {
        File* first, * second;
        first = head[user]->child;
        second = first->brother;
        while (second != NULL)
        {
            first = second;
            second = second->brother;
        }
        first->brother = t;
    }
}

void display(int n, File* p)//以树形结构显示所有文件
{
    printf("\n");
    for (int i = 0; i < n; i++)
    {
        printf(" ");
    }
    printf("%s", p->fileName);

    if (p->child != NULL)
    {
        p = p->child;
        while (p != NULL)
        {
            if (!p->flag) {
                display(n + 1, p);
            }

            else {
                printf("\n");
                for (int i = 0; i < n + 1; i++)
                {
                    printf(" ");
                }
                printf("%s", p->fileName);
            }

            p = p->brother;
        }
    }

    return;
}

void operation()
{
    int i, j;
    printf("\n\n**********树形结构目录文件系统**********");
    printf("\n选择操作:\n-----1.创建文件\n"
        "-----2.删除文件\n"
        "-----3.打开文件\n"
        "-----4.修改文件\n"
        "-----5.关闭文件\n"
        "-----6.查看文件\n"
        "-----7.创建用户\n"
        "-----0.退出程序");
    printf("\n请选择:");
    scanf_s("%d", &i);
    if (i == 1)//创建文件
    {
        if (sum == N*M) {
            printf("\n系统文件已满!");
            return;
        }

        if (head[0] == NULL) {
            printf("\n系统还没有用户!");
            return;
        }

        printf("\n请选择用户:");
        printf("\n-----0.%s", head[0]->fileName);
        if (head[1] != NULL) {
            printf("\n-----1.%s", head[1]->fileName);
        }
        printf("\n请选择:");
        scanf_s("%d", &j);

        if (num[j] == M) {
            printf("\n该用户文件已满!无法创建新文件。");
            return;
        }

        insertItem(j);
    }
    else if (i == 2)//删除文件
    {
        if (head[0] == NULL) {
            printf("\n系统还没有用户!");
            return;
        }

        printf("\n请选择用户:");
        printf("\n-----0.%s", head[0]->fileName);
        if (head[1] != NULL) {
            printf("\n-----1.%s", head[1]->fileName);
        }
        printf("\n请选择:");
        scanf_s("%d", &j);
        
        p = NULL;
        printf("\n请输入要删除的文件名:");
        scanf_s("%s", s, sizeof(s));
        find = 0;
        search(head[j]);

        if (p == NULL) {
            printf("\n找不到文件!");
            return;
        }

        --sum;
        --num[j];

        if (p == head[j]->child)
        {
            head[j]->child = p->brother;
            free(p);
            return;
        }

        File* first, *second;
        first = head[j]->child;
        second = first->brother;
        while (second != p && second != NULL)
        {
            first = second;
            second = second->brother;
        }
        first->brother = p->brother;
        strcpy_s(p->content, sizeof(s), " ");
        free(p);
    }
    else if (i == 3)//打开文件
    {
        if (head[0] == NULL) {
            printf("\n系统还没有用户!");
            return;
        }
        if (open != NULL) {
            printf("\n已经打开%s!一次只能打开一个文件。", open->fileName);
            return;
        }

        printf("\n请选择用户:");
        printf("\n-----0.%s", head[0]->fileName);
        if (head[1] != NULL) {
            printf("\n-----1.%s", head[1]->fileName);
        }
        printf("\n请选择:");
        scanf_s("%d", &j);

        p = NULL;
        printf("\n请输入要打开的文件名:");
        scanf_s("%s", s, sizeof(s));
        find = 0;
        search(head[j]);

        if (p == NULL) {
            printf("\n找不到文件!");
            return;
        }

        printf("\n打开%s", p->fileName);
        open = p;
        printf("\n%s", p->content);
    }
    else if (i == 4)//修改文件
    {
        if (head[0] == NULL) {
            printf("\n系统还没有用户!");
            return;
        }
        if (open != NULL) {
            printf("\n已经打开%s!一次只能打开一个文件。", open->fileName);
        }

        printf("\n请选择用户:");
        printf("\n-----0.%s", head[0]->fileName);
        if (head[1] != NULL) {
            printf("\n-----1.%s", head[1]->fileName);
        }
        printf("\n请选择:");
        scanf_s("%d", &j);

        p = NULL;
        printf("\n请输入要修改文件名:");
        scanf_s("%s", s, sizeof(s));
        find = 0;
        search(head[j]);

        if (p == NULL) {
            printf("\n找不到文件!");
            return;
        }
        if (p->limit) {
            printf("\n%s是只读文件!", p->fileName);
            return;
        }

        printf("\n打开%s", p->fileName);
        open = p;
        printf("\n%s", open->content);
        printf("\n请输入修改后内容:\n");
        scanf_s("%s", p->content, sizeof(s));
    }
    else if (i == 5) {//关闭文件
        if (head[0] == NULL) {
            printf("\n系统还没有用户!");
            return;
        }
        if (open == NULL) {
            printf("\n当前没有打开文件!");
            return;
        }

        printf("\n关闭文件%s!",open->fileName);
        open = NULL;
    }
    else if (i == 0) {//退出程序
        exit(0);
    }
    else if (i == 7) {//创建用户
        if (head[0] == NULL) {
            init(0);
            return;
        }
        if (head[1] == NULL) {
            init(1);
            return;
        }
        printf("\n用户已满!无法创建新用户。");
    }
    else if (i == 6) {
        if (head[0] == NULL) {
            printf("\n系统还没有用户!");
            return;
        }

        printf("\n请选择用户:");
        printf("\n-----0.%s", head[0]->fileName);
        if (head[1] != NULL) {
            printf("\n-----1.%s", head[1]->fileName);
        }
        printf("\n请选择:");
        scanf_s("%d", &j);

        display(0, head[j]);
    }
    else printf("\n没有这个选项!");
}

int main()
{
    for (int i = 0; i < N * M; ++i)
    {
        strcpy_s(file[i], sizeof(s), " ");
    }
    for (int i = 0; i < N; i++)
    {
        head[i] = NULL;
    }
    p = NULL;
    open = NULL;
    while (1)
    {
        operation();
    }
    return 0;
}

 

  • 18
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赴星辰大海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值