操作系统实验:文件管理 C语言

设计实现一个模拟文件系统。包括文件目录管理、存储空间管理、文件创建、删除、读、写等基本操作功能。测试环境 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消失

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值