原题:实验四 文件系统---设计测试实验
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;
}