设计实现一个模拟文件系统。包括文件目录管理、存储空间管理、文件创建、删除、读、写等基本操作功能。测试环境 DEVc++
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include <iomanip>
using namespace std;
const int mem_maxsize = 8 * 1024; // 8M最大内存空间
const int block_size = 512; // 盘块大小
// 文件结构
typedef struct file
{
string name; // 文件名
int size; // 文件大小
int start_bid; // 首盘块号
file* next; // 同一目录下一文件
};
// 文件夹结构
typedef struct folder
{
string name; // 目录名
folder* par_folder; // 父目录
folder* sub_folder; // 子目录
folder* next; // 兄弟目录
file* sub_file; // 子文件
};
// 盘块结构
typedef struct free_block {
int block_id; // 盘块号
int start_add; // 开始地址
int mem_size; // 内存大小
int remain_mem_size; // 剩余空间
int state; // 是否被占用
free_block* next; // 下一空闲盘块
};
folder* home; // 根目录
folder* cur_catalog; // 当前目录
free_block* fb_arr[mem_maxsize / block_size + 1]; // 盘块指针数组
// 初始化内存空间
void init_mem_system() {
int bid = 0;
for (int i = 0; i < mem_maxsize; i += 512) {
free_block* fbt = new free_block;
fbt->block_id = bid;
fbt->start_add = i;
fbt->mem_size = 512;
fbt->remain_mem_size = 512;
fbt->state = 0;
fbt->next = NULL;
fb_arr[bid] = fbt;
bid++;
}
fb_arr[bid] = NULL;
}
// 初始化文件系统
folder* init_file_system() {
folder* home = new folder;
home->name = "home";
home->par_folder = NULL;
home->sub_file = NULL;
home->sub_folder = NULL;
cur_catalog = home;
return home;
}
// 显示内存空间
void show_mem() {
string str = "";
cout << str.assign(14, '#') << " MEM " << str << endl;
cout << setw(8) << "盘块号" << setw(10) << "是否分配" << setw(10) << "内存大小"
<< setw(14) << "剩内存大小" << endl;
free_block** fbt = fb_arr;
for (; *fbt; fbt++)
{
cout << setw(8) << (*fbt)->block_id << setw(10) << (*fbt)->state << setw(10) << (*fbt)->mem_size
<< setw(14) << (*fbt)->remain_mem_size << endl;
}
cout << endl;
}
// 显示当前目录
void show_catalog() {
string str = "";
cout << str.assign(14, '#') << " FOLDER " << str << endl;
folder* fdt = cur_catalog->sub_folder;
for (; fdt; fdt = fdt->next) {
cout << str.assign(18 - fdt->name.size() / 2, ' ')
<< fdt->name << str << endl;
}
cout << endl;
cout << str.assign(15, '#') << " FIlE " << str << endl;
file* ft = cur_catalog->sub_file;
for (; ft; ft = ft->next) {
cout << str.assign(18 - ft->name.size() / 2, ' ')
<< ft->name << str << endl;
}
cout << endl;
}
// 判断文件夹是否存在
bool is_folder_exist(string name) {
folder* fdt = cur_catalog->sub_folder;
for (; fdt; fdt = fdt->next) {
if (fdt->name == name) {
return true;
}
}
return false;
}
// 判断文件是否存在
bool is_file_exist(string name) {
file* ft = cur_catalog->sub_file;
for (; ft; ft = ft->next) {
if (ft->name == name) {
return true;
}
}
return false;
}
// 创建目录
int create_folder() {
cout << "##请输入文件夹名称##" << endl;
string name;
cin >> name;
if (is_folder_exist(name)) {
return -1;
}
folder* fdt = new folder;
fdt->name = name;
fdt->par_folder = cur_catalog;
fdt->sub_folder = NULL;
fdt->sub_file = NULL;
fdt->next = NULL;
if (cur_catalog->sub_folder == NULL) {
cur_catalog->sub_folder = fdt;
}
else {
folder* fd = cur_catalog->sub_folder;
for (; fd->next; fd = fd->next);
fd->next = fdt;
}
cout << "##文件夹创建成功!##" << endl << endl;
return 0;
}
// 释放空间
int free_mem(file* f) {
free_block* fb = fb_arr[f->start_bid];
for (; fb; ) {
fb->state = 0;
fb->remain_mem_size = fb->mem_size;
free_block* t = fb;
fb = fb->next;
t->next = NULL;
}
return 0;
}
// 递归删除当前目录的所有文件和子目录
void delete_sub_folder(folder* fd) {
if (fd == NULL) {
return;
}
file* f = fd->sub_file;
for (; f; ) {
file* ft = f;
f = f->next;
free_mem(ft);
delete(ft);
}
folder* fdt = fd->sub_folder;
for (; fdt;) {
delete_sub_folder(fdt);
folder* t = fdt;
fdt = fdt->next;
delete(t);
}
delete(fd);
}
// 删除目录
int delete_folder() {
cout << "##请输入文件夹的名称##" << endl;
string name;
cin >> name;
if (!is_folder_exist(name)) {
cout << "##文件夹不存在!##" << endl << endl;
return -1;
}
folder* fdt = cur_catalog->sub_folder;
if (cur_catalog->sub_folder->name == name) {
cur_catalog->sub_folder = cur_catalog->sub_folder->next;
delete_sub_folder(fdt);
}
else {
for (; fdt->next->name != name; fdt = fdt->next);
folder* t = fdt->next;
fdt->next = fdt->next->next;
delete_sub_folder(t);
}
cout << "##文件夹删除成功!##" << endl << endl;
}
// 打开目录
int open_folder() {
cout << "##请输入文件夹名称##" << endl;
string name;
cin >> name;
if (!is_folder_exist(name)) {
cout << "##文件夹不存在!##" << endl << endl;
return -1;
}
folder* fdt = cur_catalog->sub_folder;
for (; fdt->name != name; fdt = fdt->next);
cur_catalog = fdt;
}
// 分配内存
int allot_mem(file* f) {
int start_block_id = 0;
int file_size = f->size;
free_block* fb = NULL;
free_block** fbt = fb_arr;
for (; *fbt; fbt++) {
if ((*fbt)->state == 0) {
if ((*fbt)->mem_size >= f->size) {
(*fbt)->state = 1;
(*fbt)->remain_mem_size -= f->size;
return (*fbt)->block_id;
}
else {
if (file_size == f->size) {
start_block_id = (*fbt)->block_id;
file_size -= (*fbt)->mem_size;
(*fbt)->remain_mem_size = 0;
(*fbt)->state = 1;
fb = (*fbt);
}
else {
if ((*fbt)->mem_size >= file_size) {
(*fbt)->remain_mem_size -= file_size;
(*fbt)->state = 1;
fb->next = (*fbt);
fb = fb->next;
return start_block_id;
}
else {
(*fbt)->remain_mem_size = 0;
(*fbt)->state = 1;
fb->next = (*fbt);
fb = fb->next;
file_size -= (*fbt)->mem_size;
}
}
}
}
}
return -1;
}
// 创建文件
int create_file() {
cout << "##请输入文件名称和大小##" << endl;
string name;
int size;
cin >> name >> size;
if (is_file_exist(name)) {
return -1;
}
file* ft = new file;
ft->name = name;
ft->size = size;
ft->next = NULL;
if ((ft->start_bid = allot_mem(ft)) != -1) {
if (cur_catalog->sub_file == NULL) {
cur_catalog->sub_file = ft;
}
else {
file* f = cur_catalog->sub_file;
for (; f->next; f = f->next);
f->next = ft;
}
}
else {
cout << "##内存空间不足,创建文件失败!##" << endl << endl;
}
cout << "##文件创建成功!##" << endl << endl;
return 0;
}
// 删除文件
int delete_file() {
cout << "##请输入文件名称##" << endl;
string name;
cin >> name;
if (!is_file_exist(name)) {
cout << "##文件不存在!##" << endl << endl;
return -1;
}
file* f;
file* ft = cur_catalog->sub_file;
if (cur_catalog->sub_file->name == name) {
f = ft;
cur_catalog->sub_file = cur_catalog->sub_file->next;
}
else {
for (; ft->next->name != name; ft = ft->next);
f = ft->next;
ft->next = ft->next->next;
}
free_mem(f);
delete(f);
cout << "##文件删除成功!##" << endl << endl;
}
// 读取文件
int read_file() {
cout << "##请输入文件名称##" << endl;
string name;
cin >> name;
if (is_file_exist(name)) {
file* ft = cur_catalog->sub_file;//在当前目录下找到文件
for (; ft; ft = ft->next) {
if (ft->name == name) { //如果名字查到 退出
break;
}
}
free_block* fbt = fb_arr[ft->start_bid]; //空闲的磁盘号产给他
//cout << "##";
cout<<"当前所在的磁盘号为:";
while (fbt)
{
cout << fbt->block_id;//找到当前磁盘号id
if (fbt->next) {
cout << "-";
}
fbt = fbt->next;//传到下一个结点
}
cout << """""" << endl;
}
else {
cout << "## 文件不存在! ##" << endl;
}
return 0;
}
// 追加写入
int write_file() {
cout << "##请输入文件名称和写入长度##" << endl;
string name;
int len;
cin >> name >> len;
if (is_file_exist(name)) {
file* ft = cur_catalog->sub_file; //转到当前目录下
for (; ft; ft = ft->next) { // 查看是否有这个文件
if (ft->name == name) {
break;
}
}
free_block* fbt = fb_arr[ft->start_bid]; //空闲盘块写入
for (; fbt->next; fbt = fbt->next);
if (len <= fbt->remain_mem_size) { //比较剩余空间
fbt->remain_mem_size -= len; //剩余空间减少
}
else { //创建新文件
file* t = new file;
t->size = len;
t->size -= fbt->remain_mem_size;
fbt->remain_mem_size = 0;
int sub_bid;
if ((sub_bid = allot_mem(t)) != -1)
{
fbt->next = fb_arr[sub_bid]; //
}
delete(t);
}
}
return 0;
}
// 返回上一目录
int return_last_catalog() {
if (cur_catalog == home) {
cout << "##已是根目录##" << endl << endl;
}
cur_catalog = cur_catalog->par_folder;
return 0;
}
int main() {
init_mem_system();
home = init_file_system();
int cmd;
while (true)
{
show_catalog();
cout << setw(14) << "#1创建文件夹 " << setw(14) << "#2删除文件夹"
<< setw(14) << "#3打开文件夹" << setw(12) << "#4创建文件"
<< setw(12) << "#5删除文件" << setw(12) << "#6读取文件"
<< setw(12) << "#7写入文件" << setw(14) << "#8返回上一层" << setw(16) << "#9查看磁盘空间" << endl;
cin >> cmd;
switch (cmd)
{
case 1:
create_folder();
break;
case 2:
delete_folder();
break;
case 3:
open_folder();
break;
case 4:
create_file();
break;
case 5:
delete_file();
break;
case 6:
read_file();
break;
case 7:
write_file();
break;
case 8:
return_last_catalog();
break;
case 9:
show_mem();
break;
default:
break;
}
}
}
文件创建部分
先创建文件夹,在文件夹中创建文件,设置好名字和文件大小,创建多个文件在不同的磁盘中,
读部分
读写文件时输入增加的内存大小,读取文件时输出磁盘的编号,删除文件,所在的磁盘内存恢复
测试如下:
创建文件夹 命名为001
然后打开文件夹后 创建文件1 和2 内存大小为128kb(自己设计大小 不易过大)
可以读取文件 1和2 文件1的磁盘号 查看磁盘内存 磁盘0和磁盘1的内存减少了相应的内存 128kb
写入文件1 内存1024kb 查看磁盘号为0-2-3 用内存代替输入的内容
删除部分
删除文件2 文件夹中文件2消失