/*
*模拟文件管理
*/
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
using namespace std;
#define MAX 1000
/*
*定义文件数据结构
*/
typedef struct FCB
{
char file_name[20];
bool file_protect[3]; //只读、不可访问、不可删除
int head, tail; //文件指向存储位置的头尾
int file_length;
bool isOpen; //是否已打开
FCB *next;
}FCB;
char space[10000]; //磁盘
int spaceSizeLeft = 10000;
int fileCount = 0;
int openCount = 0;
//空闲表
typedef struct rest {
int begin;
int size;
}rest;
typedef struct restList {
rest r[MAX];
int length;
}restList;
restList rl;
bool createFile(FCB *head);
bool deleteFile(FCB *head);
bool readFile(FCB *head);
bool writeFile(FCB *head);
bool openFile(FCB *head);
bool closeFile(FCB *head);
void viewSpace(FCB *head);
int cmp1(const void *a, const void*b); //按空闲区开始位置排序
int cmp2(const void *a, const void*b); //按空闲区大小排序
int main() {
rl.length = 1;
rl.r[0].begin = 0;
rl.r[0].size = 10000;
FCB *head = (FCB*)malloc(sizeof(FCB));
head->next = NULL;
while (1) {
cout << "欢迎使用文件管理系统" << endl;
cout << "输入对应数字使用对应功能" << endl;
cout << "1.创建文件" << endl;
cout << "2.删除文件" << endl;
cout << "3.打开文件" << endl;
cout << "4.关闭文件" << endl;
cout << "5.读文件" << endl;
cout << "6.写文件" << endl;
cout << "7.查看磁盘情况" << endl;
int input;
cin >> input;
switch (input) {
case 1:
createFile(head);
break;
case 2:
deleteFile(head);
break;
case 3:
openFile(head);
break;
case 4:
closeFile(head);
break;
case 5:
readFile(head);
break;
case 6:
writeFile(head);
break;
case 7:
viewSpace(head);
break;
default:
cout << "输入错误,请重新输入" << endl;
}
system("pause");
system("cls");
}
}
bool createFile(FCB* head) {
char name[20];
bool protect[3];
int length;
cout << "依次输入文件名,是否可修改,是否可访问,是否可删除,文件大小" << endl;
cin >> name >> protect[0] >> protect[1] >> protect[2] >> length;
if (length > spaceSizeLeft) {
cout << "文件过大" << endl;
return false;
}
FCB *q = head;
FCB *p = head->next;
while (p) {
if (strcmp(name, p->file_name) == 0) {
cout << "文件名已存在" << endl;
return false;
}
q = p;
p = p->next;
}
//算法: 最佳适应算法(best fit)
//找一个空闲区
//对空闲表按空闲区大小排序
bool isFind = false;
qsort(rl.r, rl.length, sizeof(rest), cmp2);
int i;
for (i = 0; i < rl.length; ++i) {
if (rl.r[i].size >= length) {
isFind = true;
break;
}
}
if (!isFind) {
cout << "找不到空闲区,文件创建失败" << endl;
return false;
}
FCB *newFile = (FCB*)malloc(sizeof(FCB));
newFile->next = NULL;
newFile->head = rl.r[i].begin;
newFile->tail = rl.r[i].begin + rl.r[i].size;
strcpy(newFile->file_name, name);
newFile->file_length = length;
for (int k = 0; k < 3; ++k) {
newFile->file_protect[k] = protect[k];
}
fileCount++;
//更新空闲表
if (rl.r[i].size == newFile->file_length) {
for (int j = i; j < rl.length; ++j) {
rl.r[j] = rl.r[j + 1];
}
rl.length--;
}
else {
rl.r[i].begin = rl.r[i].begin + newFile->file_length;
rl.r[i].size = rl.r[i].size - newFile->file_length;
}
spaceSizeLeft -= newFile->file_length;
cout << "文件" << newFile->file_name << "创建成功" << endl;
q->next = newFile;
newFile->isOpen = false;
return true;
}
bool deleteFile(FCB *head) {
char name[20];
cout << "输入删除的文件名" << endl;
cin >> name;
FCB *p = head->next;
FCB *q = head;
while (p) {
if (strcmp(name, p->file_name) == 0) {
break;
}
else {
p = p->next;
q = q->next;
}
}
if (!p) {
cout << "文件不存在" << endl;
return false;
}
if (!p->file_protect[2]) {
cout << "文件不可删除" << endl;
return false;
}
if (p->isOpen) {
cout << "文件未关闭" << endl;
return false;
}
rl.r[rl.length].begin = p->head;
rl.r[rl.length].size = p->file_length;
rl.length++;
fileCount--;
q->next = p->next;
free(p);
cout << "文件" << name << "已删除" << endl;
//TODO:合并空闲区
qsort(rl.r, rl.length, sizeof(rest), cmp1);
for (int i = 0; i < rl.length - 1; ++i) {
if (rl.r[i].begin + rl.r[i].size + 1 == rl.r[i + 1].begin) {
rl.r[i].size = rl.r[i].size + rl.r[i + 1].size;
for (int j = i; j < rl.length - 1; ++j) {
rl.r[j] = rl.r[j + 1];
}
--rl.length;
}
}
return true;
}
void viewSpace(FCB *head) {
cout << "当前磁盘文件数量:" << fileCount << endl;
cout << "已打开的文件数量:" << openCount << endl;
cout << "磁盘总空间:10000字节" << endl;
cout << "磁盘已用空间:" << 10000 - spaceSizeLeft << "字节" << endl;
cout << "磁盘可用空间:" << spaceSizeLeft << "字节" << endl;
}
bool openFile(FCB *head) {
cout << "请输入打开的文件名" << endl;
char name[20];
cin >> name;
FCB *p = head->next;
FCB *q = head;
while (p) {
if (strcmp(name, p->file_name) == 0) {
break;
}
else {
p = p->next;
q = q->next;
}
}
if (!p) {
cout << "文件不存在" << endl;
return false;
}
if (!p->file_protect[1]) {
cout << "文件不可访问" << endl;
return false;
}
cout << "文件" << name << "已经打开" << endl;
p->isOpen = true;
openCount++;
return true;
}
bool closeFile(FCB *head) {
cout << "请输入关闭的文件名" << endl;
char name[20];
cin >> name;
FCB *p = head->next;
FCB *q = head;
while (p) {
if (strcmp(name, p->file_name) == 0) {
break;
}
else {
p = p->next;
q = q->next;
}
}
if (!p) {
cout << "文件不存在" << endl;
return false;
}
if (!p->isOpen) {
cout << "文件未打开" << endl;
return false;
}
p->isOpen = false;
openCount--;
cout << "文件" << name << "已关闭" << endl;
return true;
}
bool writeFile(struct FCB *head) {
cout << "请输入写入的文件名" << endl;
char name[20];
cin >> name;
FCB *p = head->next;
FCB *q = head;
while (p) {
if (strcmp(name, p->file_name) == 0) {
break;
}
else {
p = p->next;
q = q->next;
}
}
if (!p) {
cout << "文件不存在" << endl;
return false;
}
if (!p->isOpen) {
cout << "文件未打开" << endl;
return false;
}
if (!p->file_protect[0]) {
cout << "文件只读" << endl;
return false;
}
cout << "请输入往文件写入的内容,不要超过文件长度" << endl;
char* content = (char*)malloc(p->file_length * sizeof(char));
cin >> content;
for (int i = 0; i < p->file_length; ++i) {
space[p->head + i] = content[i];
}
cout << "写入成功" << endl;
return true;
}
bool readFile(FCB *head) {
cout << "请输入读的文件名" << endl;
char name[20];
cin >> name;
FCB *p = head->next;
FCB *q = head;
while (p) {
if (strcmp(name, p->file_name) == 0) {
break;
}
else {
p = p->next;
q = q->next;
}
}
if (!p) {
cout << "文件不存在" << endl;
return false;
}
if (p->isOpen == false) {
cout << "文件未打开" << endl;
return false;
}
char* content = (char*)malloc(p->file_length * sizeof(char));
for (int i = 0; i < p->file_length; ++i) {
content[i] = space[p->head + i];
}
cout << "文件" << name << "的内容是" << endl;
cout << content << endl;
return true;
}
int cmp1(const void *a, const void*b) {
return (*(rest*)a).begin - (*(rest*)b).begin;
}
int cmp2(const void *a, const void*b) {
return (*(rest*)a).size - (*(rest*)b).size;
}