OS课设:实现二级文件目录系统

先从头才是撤,写到现在真的感觉是令人肝疼的一份课设。2019年6月27日19:16:09

老师就不说了,在站内可以直接搜到,所以还是悄悄地抱怨,WOC XiaoZhao


废话不多讲了,开始这份分析报告把,希望能帮上我的读者。

本人的底层实现来自于这位大哥的好心链接,给我了很多指导性的启发,不过他也有致命的错误,也是我为什么这么肝疼的原因了(设计实现一个文件系统,既然要以链表的形式实现连续式存储文件系统,为什么不做存储空间的回收)

附带大哥链接:https://blog.csdn.net/huangqiang1363/article/details/50592633

本人在实现:1空间分配,2空间合并,3优先排序方面真的下了很大的功夫,毕竟单链表实现连续性,实现起来确实可能不如同学使用的索引节点好用。本人的拙见……


课设题目:操作系统之实现二级文件目录系统

时间,,,乌拉乌拉

其实,刚拿到这个题目时,我真的没有思路,随后我就对着老师的课设指导书进行研究,对二级文件系统的演示这个课题的每个要求进行分析,总算是有了思路。下面给出我的分析。
文件系统演示
一、课程设计目的
使学生熟悉文件管理系统的设计方法;加深对所学各种文件操作的了解及其操作方法的特点。
//既然是基于控制台的,我们可以更改颜色玩玩
二、课程设计内容
设计一个简单的多用户文件系统。即 //和后面一样,用结构体数组实现
①在系统中用一个文件来模拟一个磁盘; //switch语句或者if-else语句实现,既然这里说到了 用一个文件去模拟一个磁盘,换句话说,在你的课设里,必须要有磁盘空间分配的思路在里面,不然就不是模拟磁盘了。
②此系统至少有:Create、delete、open、close、read、write等和部分文件属性的功能。
③实现这个文件系统。 //文件系统要实现
④能实际演示这个文件系统。//cmd演示即可
基本上是进入一个界面(此界面就是该文件系统的界面)后,可以实现设计的操作要求。

三、课程设计指导
1)设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。 //三个数组的大小分别为 10、10、5
//一次运行用户最多可以打开5个文件如何实现? 在用户文件里面加变量判断,用户每打开一个就+1,
//每次用户最多可保存10个文件如何实现? 很明显,同时保存我们是无法做到的,无论是谁,都无法做到,也就是说还是一个个保存的,那么同样可以设置变量判断。如果保存的较多,那么只好请用户单独关闭某些指定的文件。

2)程序采用二级文件目录(即设置主目录MFD)和用户文件目录(UFD)。另外,为打开文件设置了运行文件目录(AFD)。 //存放各个用户目录的文件夹、用户目录
//是说运行的所有文件用一个目录层次表示吗
3)为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。 //整型的变量判断是否读写完成了 下面的pointer
4)因系统小,文件目录的检索使用了简单的线性搜索。 //链表的顺序查找
5)文件保护简单使用了三位保护码:允许读写执行、对应位为 1,对应位为0,则表示不允许读写、执行。 //标记变量即可实现
6)程序中使用的主要设计结构如下:主文件目录和用户文件目录(MFD、UFD),打开文件目录(AFD)即运行文件目录,如图5.1所示。//主要的结构体设计

还有MFD、UFD、AFD最好全部存到文件里面去,不然每次都要输入,十分麻烦,而且不能通过看文件 查看到自己的实验现象,着实不便。
参考的数据结构设计如下
struct TYPE_UFD //用户文件目录
{
string File_Name; //文件名
bool Read; //读保护码,true为可读
bool Write; //写保护码,true为可写
bool Execute; //执行保护码,true为可执行
int Length_File; //文件长度
}; //用户文件目录和用户打开的文件目录是不是都各有自己的属性
struct TYPE_MFD //主文件目录
{
string User_Name; //用户名
TYPE_UFD *Pointer; //用户文件目录指针
};
//很明显,第三个结构体没有指针域,但我们是需要指针域的,还有下面红色部分可以合在一个整型变量里面的
struct TYPE_AFD //打开文件目录
{
int File_ID; //打开的文件号
boolRead;//读保护码,true为可读
boolWrite;//写保护码,true为可写
boolExecute;//执行保护码,true为可执行
int Pointer; //读写指针
};
7)文件系统结构如图5.2所示
//很明显,这里要用到的数据结构是 链表
    
8)文件系统算法的流程图如图5.3所示。
                             
图5.3文件系统算法的流程图
//这里告诉了你 main函数的主要调用的函数顺序 
9)注意对于物理块的访问(包括访问指针,空闲位)需要经过输入输出,相当于通过定位对文件进行读写。打开文件目录(AFD)是在内存中,由打开文件时创建。
好了,分析完了,就要开始编写代码了,下面附上我小小的代码,还有很多需要修改的地方,做的不好的地方,大神就请原谅,也希望多多指点我。
--------------------- 
作者:o0非诚勿扰0o 
来源:CSDN 
原文:https://blog.csdn.net/huangqiang1363/article/details/50592633 


代码实现Code

下面是我实现整体结构的文件·

1 OSHead.h头文件

#ifndef OSHEAD_H_INCLUDED
#define OSHEAD_H_INCLUDED

#include<cmath>
#include<ctime>
#include<string>
#include<conio.h>
#include<fstream>
#include<cstdlib>
#include<iostream>
#include<windows.h>
using namespace std;

typedef struct UFD
{
	string File_name;         //文件名
	int Start;                //文件在磁盘存储空间的起始地址
	int Protect;              //文件的属性
	int File_length;           //文件的长度
	int Max_File_length;         //文件的最大长度
	struct UFD *next;
	int i=0;
}UFD,*UFD_ptr;

typedef struct MFD
{
	string User_name;
	string User_passwd;
	UFD *Ufd_next;
	int End;
	struct MFD *next;
}MFD,*MFD_ptr;




typedef struct AFD
{
	string File_name;
	int File_length;
	int Start;
	int Protect;
	int Pointer;    //根据这个指针的值去完成用户的要求  读写指针
	int Max_File_length;
	struct AFD *next;
}AFD,*AFD_ptr;

#endif // OSHEAD_H_INCLUDED

2.Main.cpp文件
 

#include"OSHead.h"

#define MaxDisk 512*1024   //一个扇区512字节,假设有1024个扇区,模拟磁盘的大小
int Max_User=10;
int Max_Open=5;
int Max_End=0;
UFD_ptr pufd=NULL;
MFD_ptr pmfd=NULL;
AFD_ptr pafd=NULL;
char User_name[30];   //存放当前用户的用户名
char flag='n';
char Disk_Size[MaxDisk];    //最后在打印输出的时候,用RWX表示即可

int zone[10][2];
int x,y;

typedef struct Disk_Table
{
	int Max_length;      //最大长度
	int Start;          //开始位置
}Disk_Node;
Disk_Node Disk_Head;

void clean();
void sort();

void Init_Disk()
{
	Disk_Head.Max_length=MaxDisk;
	Disk_Head.Start=0;
}

bool Init_MFD()
{
	pmfd=(MFD *)new MFD;   //带头节点的单向链表
	MFD *p=pmfd;
	ifstream ifs("MFD.txt");  //文件的输入流对象
	if(!ifs)
	{
		cerr<<"错误:无法打开文件"<<endl;
		p->next=NULL;
		p->Ufd_next=NULL;
		return false;
	}
	while(!ifs.eof())
	{
		p->next=(MFD *)new MFD;
		ifs>>p->next->User_name>>p->next->User_passwd>>p->next->End;
		if(p->next->End>Max_End)
			Max_End=p->next->End;
		p=p->next;
		p->Ufd_next=NULL;
		p->next=NULL;
	}
	ifs.close();
	return true;
}

void Print_UFD()
{
	UFD *p=pufd->next;
	if(!p)
	{
		cout<<"抱歉,该用户没有创建任何文件,请先创建!!!"<<endl;
		return ;
	}
	cout<<"文件名\t\t最大文件长度\t文件权限\t起始位置\t文件长度"<<endl;
	while(p)
	{
		cout<<p->File_name<<"\t\t"<<p->Max_File_length;
		if(p->Protect==0)
			cout<<"\t\t"<<"---";
		else if(p->Protect==1)
			cout<<"\t\t"<<"r-x";
		else if(p->Protect==2)
			cout<<"\t\t"<<"rwx";
		cout<<"\t\t"<<p->Start;
		cout<<"\t\t"<<p->File_length<<endl;
		p=p->next;
	}
}

bool Init_UFD(char *name)
{
	ifstream ifs(name);
	pufd=(UFD *)new UFD;
	UFD *p=pufd;
	char temp[MaxDisk];
	bool Index=false;
	if(!ifs)
	{
		cerr<<"错误:无法打开文件或尚未创建文件"<<endl;
		p->next=NULL;
		return false;
	}
	while(!ifs.eof())
	{
		memset(temp,'\0',sizeof(temp));
		p->next=(UFD *)new UFD;
		if(!Index)
		{
			pmfd->Ufd_next=p->next;
			Index=true;
		}
		ifs>>p->next->File_name>>p->next->Max_File_length>>p->next->Protect>>p->next->Start>>p->next->File_length;
		ifs>>temp;
		if(temp[0]=='#')
			temp[0]='\0';
		for(int i=p->next->Start,j=1;j<=p->next->Max_File_length-1;i++,j++)
		{
			Disk_Size[i]=temp[j-1];
			if(!Disk_Size[i])
				break;
		}
		Disk_Head.Max_length-=p->next->Max_File_length;
	//	Disk_Head.Start+=p->next->Max_File_length;
		p=p->next;
		p->next=NULL;
	}
	ifs.close();
	return true;
}

void Rename_File()
{
	string File_name;
	UFD *temp=pufd;
	char Index;
SD:
	cout<<"请输入文件的名字:"<<endl;
	cin>>File_name;
	while(temp)
	{
		if(temp->File_name==File_name)
		{
			cout<<"请输入新的文件名:"<<endl;
			cin>>File_name;
			temp->File_name=File_name;
			break;
		}
		temp=temp->next;
	}
	if(!temp)
	{
		cout<<"抱歉,输入的文件不存在,无法完成重命名文件操作,是否继续操作<y/n>?"<<endl;
		cin>>Index;
		if(Index=='y')
			goto SD;
		else
			return ;
	}
	else
		cout<<"修改成功!!!"<<endl;
}
bool User_Check()
{
	string User_passwd;
	int Count=0;
	while(1)
	{
		cout<<"请输入用户名:";
		cin>>User_name;
INIT:
		cout<<"请输入密码:";
		cin>>User_passwd;
		MFD *p=pmfd->next;
		char temp[30];
		memset(temp,'\0',sizeof(temp));
		strcpy(temp,User_name);
		Count++;
		while(p)
		{
			if(User_name==p->User_name)
			{
				if(User_passwd==p->User_passwd)
					cout<<"登入成功."<<endl;
				else
				{
					cout<<"抱歉,密码错误,登陆失败,请重新输入!!!"<<endl;
					if(Count==3)
					{
						cout<<"密码错误次数过多,系统运行结束!!!"<<endl;
						return false;
					}
					goto INIT;
				}
				strcat(temp,".txt");
				Init_UFD(temp);
	//			Print_UFD();
				Disk_Head.Start=Max_End;
				return true;
			}
			p=p->next;
		}
		cout<<"用户名不存在,请重新输入!!!"<<endl;
	}
//	return false;
}
void Init_AFD()
{
	pafd=(AFD *)new AFD;
	pafd->next=NULL;
}

bool Create_MFD()//创建文件命令
{
	string User_name;
	char User_passwd[30];
	MFD *p = pmfd;
	cout<<"请输入要创建的用户名: ";
	cin>>User_name;
	cout<<"请输入"<<User_name<<"用户的密码:(默认为:admin)";
	getchar();
	cin.getline(User_passwd,30);
	if(User_passwd[0]=='\0')
		strcpy(User_passwd,"admin");
	while(p)
	{
		if(User_name==p->User_name)
		{
			cout<<"此用户名已存在!!!"<<endl;
			return false;
		}
		if(!p->next)
			break;
		p= p->next;
	}
	p->next = (MFD *)new MFD;  //尾插法
	p=p->next;
	p->User_name=User_name;
	p->User_passwd=User_passwd;
	p->End=0;
	p->next = NULL;
	p->Ufd_next = NULL;
	Max_User--;
	return true;
}  //应该是 不同的用户下的UFD文件名是不一样的啊,怎么出问题了

bool Create_UFD()//创建文件命令
{
	string File_name;
	UFD *p = pufd;
	unsigned int Protect;
	int Max_File_length;
//	AFD *pa = pafd;
	cout<<"请输入要创建的文件名: ";
	cin>>File_name;
	cout<<"请输入要创建的文件保护类型:";
	cin>>Protect;
	cout<<"请输入文件的最大容量:"<<endl;
	cin>>Max_File_length;
	while(p)
	{
		if(File_name==p->File_name)
		{
			cout<<"此文件名已存在!!!"<<endl;
			return false;
		}
		if(!p->next)
			break;
		p= p->next;
	}
    for(int i=0;i<10;i++){
        if(zone[i][1] >= Max_File_length){
            cout<<zone[i][0]<<" "<<zone[i][1]<<endl;
            p->next = (UFD *)new UFD;  //尾插法
            p=p->next;
            p->File_name=File_name;
            p->Max_File_length=Max_File_length;
            p->Start=zone[i][0];
            p->Protect = Protect;
            p->File_length = 0;     //刚创建文件时,文件是空的
            p->next = NULL;      //我觉得这部分代码有问题;用户创建了一个文件并不代表该文件就被打开了
            zone[i][0]+=Max_File_length;
            zone[i][1]-=Max_File_length;
            clean();
            sort();
            return true;
        }
    }
    for(int i=0;i<10;i++){
        cout<<zone[i][0]<<" "<<zone[i][1]<<endl;
    }
	p->next = (UFD *)new UFD;  //尾插法
	p=p->next;
	p->File_name=File_name;
	p->Max_File_length=Max_File_length;
	p->Start=Disk_Head.Start;
	p->Protect = Protect;
//	p->Time_info=      //暂定
	p->File_length = 0;     //刚创建文件时,文件是空的
	Disk_Head.Start+=Max_File_length;
	p->next = NULL;      //我觉得这部分代码有问题;用户创建了一个文件并不代表该文件就被打开了
	return true;
}

bool Delete_UFD()  //关于主目录的用户文件夹的文件删除-->先这样写,好吧    //如果文件已经打开了,是不能删除的
{
	string File_name;
	cout<<"请输入要删除的文件名:";
	cin>>File_name;
	UFD *p=pufd,*temp;
	AFD *pa=pafd;
	while(pa->next)
	{
		if(File_name==pa->next->File_name)
		{
			cout<<"抱歉,该文件已被打开,请先关闭,再进行删除操作!!!"<<endl;
			return false;
		}
	}
	while(p->next)
	{
		if(File_name==p->next->File_name)
		{
		    if(p->next->next == NULL){
                temp=p->next;
                Disk_Head.Start-=p->next->Max_File_length;
                p->next=p->next->next;  //如果说要回收模拟的磁盘空间的话,应该是回收最大长度
                //	Disk_Head.Max_length+=temp->Max_File_length;    //链表中删除了,其他的文件内容的起始位置不变即可,又没事,还是照样可以访问数据的嘛
                delete temp;
                cout<<"文件删除成功!!!"<<endl;
			return true;
		    }else{
		    x=p->next->Start;
		    y=p->next->Max_File_length;
            for(int i=0;i<10;i++){
                if(zone[i][1]==0){
                    zone[i][0]=0;
                }
                if((zone[i][0]==0) && (zone[i][1]==0)){
                 zone[i][0]=x;
                 zone[i][1]=y;
                 break;
                }
            }
            for(int i=0;i<10;i++){
                cout<<zone[i][0]<<" "<<zone[i][1]<<endl;
            }
            clean();
            sort();
			temp=p->next;
			p->next=p->next->next;  //如果说要回收模拟的磁盘空间的话,应该是回收最大长度
		//	Disk_Head.Max_length+=temp->Max_File_length;    //链表中删除了,其他的文件内容的起始位置不变即可,又没事,还是照样可以访问数据的嘛
			delete temp;
			cout<<"文件删除成功!!!"<<endl;
			return true;
		    }
		}
		p=p->next;
	}
	cout<<"抱歉,要删除的文件不存在!!!"<<endl;
	return false;
}

bool Open()
{
    string File_name;
	unsigned int Protect;
	cout<<"请输入要打开的文件名:";
    cin>>File_name;
    UFD *p=pufd->next;
	AFD *pa=pafd->next;
	while(pa)
	{
		if(File_name==pa->File_name)
		{
			cout<<"文件"<<File_name<<"已经打开!!!"<<endl;
			return true;
		}
		if(!pa->next)
			break;
		pa=pa->next;
	}
	if(!pa)     //如果找不到,或者打开的文件目录链表为空表
		pa=pafd;
	while(p)
	{
        if(File_name==p->File_name)
		{
			if(!Max_Open)
			{
				cout<<"抱歉,最多只能打开5个文件,请先关闭其他打开的文件再操作!!!"<<endl;
				return false;
			}
			if(p->Protect==0)
			{
				cout<<"抱歉,此文件不可执行任何操作!!!"<<endl;
				return false;
			}
			cout<<"请选择以什么样的方式打开文件<1-只读,2-可读可写>:";
			cin>>Protect;
			pa->next=(AFD *)new AFD;
			pa=pa->next;
			pa->File_name=p->File_name;
			pa->Start=p->Start;
			pa->File_length=p->File_length;
			pa->Max_File_length=p->Max_File_length;
			pa->Protect=Protect;
			if(Protect==1)
				pa->Pointer=0;   //Poniter取0表示此时用户无法写数据(没有空间的含义)
			else
				pa->Pointer=p->File_length;
			pa->next=NULL;
			Max_Open--;
			cout<<"文件"<<File_name<<"已经打开!!!"<<endl;
			return true;
		}
		p=p->next;
	}
	cout<<"抱歉,要打开的文件不存在!!!"<<endl;
	return false;
}
void Close()
{
	string file_name;
	UFD *pu=pufd->next;
	cout<<"请输入要关闭的文件名:";
	cin>>file_name;
	AFD *p=pafd,*temp;
	while(p&&p->next)
	{
		if(file_name==p->next->File_name)
		{
			temp=p->next;
			p->next=p->next->next;
			if(temp->Protect==2)      //可写的文件才有权把新写入的数据也保存起来嘛
			{
				while(pu)
				{
					if(temp->File_name==pu->File_name)
					{
						pu->File_length=temp->Pointer;
						break;
					}
					pu=pu->next;
				}
			}
			delete temp;
			cout<<"文件"<<file_name<<"关闭成功!!!"<<endl;
			return ;
		}
		p=p->next;
	}
	cout<<"抱歉,要关闭的文件没有被打开!!!"<<endl;
}
bool Read_File()  //因为读写都是通过修改运行文件目录的Pointer去模拟的嘛
{
	string File_name;       //你要读文件的话,你这文件肯定得在运行/打开文件目录里面,是吧
	unsigned int length;
	AFD *p=pafd->next;
	cout<<"请输入要读的文件名:";
	cin>>File_name;
	cout<<"请输入要读取的长度:";  //读取的话,实际中文件的长度并不会改变
	cin>>length;          //即读取的长度并不能保存回去,为了方便(如果用户是读数据的话,pointer始终不变)
	while(p)
	{
		if(File_name==p->File_name)
		{
			for(int i=p->Start,j=1;j<=length;i++,j++)
				cout<<Disk_Size[i];
			cout<<endl;
			cout<<"文件"<<File_name<<"读取成功!!!"<<endl;
			return true;
		}
		p=p->next;
	}
	cout<<"读取失败,文件没有打开过!!!"<<endl;
	return false;
}
bool Write_File()  //写的话,自然是运行文件目录
{
	string File_name;
	unsigned int length;
	AFD *p=pafd->next;
	char temp[MaxDisk]={'\0'};
	cout<<"请输入要写的文件名:";
	cin>>File_name;
	while(p)
	{
		if(File_name==p->File_name)
		{
			if(p->Protect!=2)
			{
				cout<<"文件"<<File_name<<"不可写"<<endl;
				return false;
			}
			cout<<"请输入要写入的长度:"<<endl;
			cin>>length;
			if(p->Pointer+length<=p->Max_File_length)
			{
				cout<<"请写入指定长度的内容:<以回车作为结束符>"<<endl;
				getchar();
				gets(temp);
				for(int i=p->Start+p->File_length,j=1;j<=strlen(temp);i++,j++)
					Disk_Size[i]=temp[j-1];
				p->Pointer += length;
				cout<<"文件"<<File_name<<"写入成功!!!"<<endl;
			}
			else
			{
				cout<<"欲写入的数据大小发生溢出,已超过文件的分配容量,写入失败!!!"<<endl;
				return false;
			}
			return true;
		}
		p=p->next;
	}
	cout<<"写入失败,文件没有打开过!!!"<<endl;
	return false;
}
void Destroy_Space()
{
	MFD *pm=pmfd;
	while(pm)
	{
		pmfd=pmfd->next;
		delete pm;
		pm=pmfd;
	}
	AFD *pa=pafd;
	while(pa)
	{
		pafd=pafd->next;
		delete pa;
		pa=pafd;
	}
	UFD *pu=pufd;
	while(pu)
	{
		pufd=pufd->next;
		delete pu;
		pu=pufd;
	}
}

void Save_MFD()
{
	ofstream ofs;        //文件的输出流对象
	ofs.open("MFD.txt");
	if(!ofs.is_open())
	{
		cout<<"The MFD can't open!!!"<<endl;
		if(flag=='y')
			cout<<"正在保存主目录用户名信息..."<<endl;
		else
			ofs.close();  //该语句待定
	}
	MFD *p=pmfd->next;
	while(p)
	{
		if(p->User_name==User_name)
			p->End=Disk_Head.Start;
		ofs<<p->User_name<<" "<<p->User_passwd<<" "<<p->End;
		if(p->next)
			ofs<<"\n";
		p=p->next;
	}
	ofs.close();
}

void Save_UFD(char *name)
{
	ofstream ofs;        //文件的输出流对象
	char temp[MaxDisk]={'\0'};
	ofs.open(name);
	if(!ofs.is_open())
	{
		cout<<"The "<<name<<"文件 can't open!!!"<<endl;
		ofs.close();  //该语句待定,这语句真的用的很妙,因为我并没有马上退出这次函数调用了
	}
	UFD *p=pufd->next;
	while(p)
	{
		memset(temp,'\0',sizeof(temp));
		for(int i=p->Start,j=1;j<=p->Max_File_length;i++,j++)
		{
			if(Disk_Size[i])
				temp[j-1]=Disk_Size[i];
			else
				break;
		}
		if(!temp[0])        //如果文件没有数据的话,就用空格表示此文件没有任何内容
			temp[0]='#';
		ofs<<p->File_name<<" "<<p->Max_File_length<<" "<<p->Protect<<" "<<p->Start<<" "<<p->File_length<<" "<<temp;
		if(p->next)
			ofs<<"\n";
		p=p->next;
	}
	ofs.close();
}

void Quit_System()
{
	AFD *pa=pafd->next;
	UFD *pu=pufd->next;
	while(pa)
	{
		if(pa->Protect==2)  //2表示可写   //1表示只读  //0表示不可操作
		{
			while(pu)
			{
				if(pa->File_name==pu->File_name)
				{
					pu->File_length=pa->Pointer;
					break;
				}
				pu=pu->next;
			}
		}
		pa=pa->next;
	}
	char temp[30];
	strcpy(temp,User_name);
	strcat(temp,".txt");
	Save_MFD();
	Save_UFD(temp);
	Print_UFD();
	Destroy_Space();
}

void Print_Help()
{
	//system("color 0b");
	cout<<"************************二级文件系统演示*************************"<<endl;
	cout<<"*\t\t命令			  说明			*"<<endl;
	cout<<"*\t\tlogin			登录系统		*"<<endl;
	cout<<"*\t\tcreate			创建文件		*"<<endl;
	cout<<"*\t\tdelete			删除文件		*"<<endl;
	cout<<"*\t\topen			打开文件		*"<<endl;
	cout<<"*\t\tclose			关闭文件		*"<<endl;
	cout<<"*\t\tread			读取文件		*"<<endl;
	cout<<"*\t\twrite			写入文件		*"<<endl;
	cout<<"*\t\tls		        显示目录		*"<<endl;
	cout<<"*\t\trename			重命文件		*"<<endl;
	cout<<"*\t\thelp			帮助菜单		*"<<endl;
	cout<<"*\t\tcls 			清除屏幕		*"<<endl;
	cout<<"*\t\tlogout 			切换用户		*"<<endl;
	cout<<"*\t\tquit			退出系统		*"<<endl;
	cout<<"*****************************************************************"<<endl;
}
void System_Init()
{
Start:
	Print_Help();
	Init_Disk();
	if(!Init_MFD())
	{
		int num;
		cout<<"主目录还未创建,是否创建<y/n>!!!"<<endl;
		cin>>flag;
		cout<<"请输入欲创建的用户文件夹的个数(1-10):"<<endl;
		cin>>num;
		if(flag=='y')
		{
			while(num--)
			{
				Create_MFD();
				if(!Max_User)
				{
					cout<<"本系统,最多支持10个用户,创建多余用户失败,请删除其他用户,再做尝试!!!"<<endl;
					return ;
				}
			}
			Save_MFD();
			cout<<"主目录已经创建完成,用户各自目录已得到保存,是否继续<y/n>!!!"<<endl;
			cin>>flag;
			if(flag=='y')
				goto Start;
		}
	}
	return ;
}


void File_System()
{
	while(1)
	{
		string Command;
		cout<<"请输入命令:";
		cin>>Command;
		if(Command=="create")
			Create_UFD();
		else if(Command=="delete")
			Delete_UFD();
		else if(Command=="open")
			Open();
		else if(Command=="close")
			Close();
		else if(Command=="read")
			Read_File();
		else if(Command=="write")
			Write_File();
		else if(Command=="quit")
		{
			Quit_System();
			break;
		}
		else if(Command=="ls")
			Print_UFD();
		else if(Command=="cls")
			system("cls");
		else if(Command=="login")
		{
			if(!User_Check())
				break;
			Init_AFD();
		}
		else if(Command=="rename")
			Rename_File();
		else if(Command=="logout")
		{
			cout<<"用户登出成功!!!"<<endl;
			Quit_System();
			System_Init();
			File_System();
		}
		else
			Print_Help();
	}
}

void clean(){
    int k,l;
    int temp;
    for(k=0;k<10;k++){
        temp=zone[k][0]+zone[k][1];
        //if(temp == Disk_Head.Start){
        //    zone[k][0]=0;
        //    zone[k][1]=0;
        //}
        for(l=0;l<10;l++){
            if(temp == zone[l][0]){
                zone[k][1]=zone[k][1]+zone[l][1];
                zone[l][0]=0;
                zone[l][1]=0;
                temp=zone[k][0]+zone[k][1]; //IIIIIIIIIIII
            }
        }
    }
}
void sort(){
    int k,l;
    int temp,temp2;
    for(k=0;k<10;k++){
        for(l=k+1;l<10;l++){
            if(zone[l][0] < zone[k][0]){

             temp=zone[k][0];
             zone[k][0]=zone[l][0];
             zone[l][0]=temp;

             temp=zone[k][1];
             zone[k][1]=zone[l][1];
             zone[l][1]=temp;
            }
        }
    }
}


int main()   //我保存,我不能连我的指针域也保存啊,这是不对的吧
{
	System_Init();
	File_System();
	return 0;
}

后面的分析等我,吃点饭,回宿舍,用自己的笔记本继续更。

三、算法分析

本文件系统实现所用的最主要的是单链表,单链表结构简单,也没实现多么复杂的算法,主要是对程序几个重要的程序进行解释。

采用单链表实现的文件存储结构为连续式存储方案。2019年6月28日23:04:09

1.Create函数

用来创建一个新文件,实现过程如下,当用户输入Create命令后,程序会优先寻找之前删除的文件的空间大小是否能够满足新文件的大小要求,如果能满足要求,那就优先分配该空间,假如,删除文件带来的空闲空间不足,则采用尾插法在链表末端新建一个新节点,存储该文件的属性信息。

既然这么分配措施,那么就很有必要实现,分配和回收

1.空间分配 :将模拟的磁盘空间分配给文件

2.空间整理:因为采用连续式存储方案,所以删除文件,被删除文件后面的文件位置是不会移动的,那就导致了,删除文件后,就留下了一段空闲空间,按照连续式存储方案,所以假设又要新建文件的话,该空间大小如果合适,就有优先分配该空间。

还有就是,当这个文件删除后,假设,后面连续的文件也被删除了,所以,就需要将这两块空间合并为一块。

再者就是,假设被删除的文件是链表最后一个文件,他的指针不指向任何文件,(p->next == NULL),所以该文件相当于指向还没有用过的空间,所以删除最后一个文件,空间的处理方案和其他的也不同,我们需要释放这块空间,让这块空间和后面的未使用过的空间重新合并。

(这里是昨天,在验收的时候发现的BUG,昨天下午,自己在机房自闭想出来的问题,和解决方案)

3.优先分配

优先分配,出现在这样的情况下,假设连续删除了好几个不连续的文件,所以产生了好几个,不连续的空闲空间块,那么按照怎样的顺序分配这些空间给符合大小的新文件呢?

答案就是从前往后,优先分配首地址小的空间。

针对上面三个需求就要,设置合适的算法实现该功能。

我写了 INT ZONE[10][2],这个数组用来记住空闲空间,删除文件时,被删除文件的首地址和文件长度,二维数组的第一项用来存储空闲空间首地址,第二项用来存储空间长度,10和2是可以改的,我只是假设记录10个空闲空间。

同时写了Clean()空间整理函数,Sort()排序函数。

这两个函数每次都是在空闲空间改变的时候调用,Clean函数用来整理和合并空闲空间,假设二维数组的某一项首地址+空间长度 = 某一项的首地址,所以就把这两块空闲空间合并,首地址为小的那个地址,空间长度扩充为第一个空间的空间长度+第二个空间的空间长度,因为第二个空间和第一个空间合并了,所以就把第二块空间初始化(首地址设为0,空间长度设为0)。

Sort函数,对这个二维数组进行按照首地址大小排序,首地址小的在前面,首地址大的在后面。

所以这样就实现了空间整理,优先分配。

Create函数在创建新文件的时候,从前往后顺序便利这个二维数组,假设有合适空间大小的空闲空间块就优先分配这块。假设空闲块中没有合适的空间块,那么就采用尾插法,在链表最后新建一个新节点,存储新文件信息。

Delete函数

感觉前面说了这么多,感觉Delete函数没有什么好说的了,用户输入所需要删除的文件名字,找到后,假设这个文件是首地址最大的文件(想到课设里面有一个问题,刚想到的一个小BUG,我是判定链表最后一个文件,链表最后一个文件不一定是首地址最大的文件,一定是最新新建的文件,所以我的课设判定条件是错误的),接着说,判定文件的时候,要判断这个文件是不是首地址最大的文件,

假设是就直接删除这个文件,

假设不是,就先将这个文件的首地址和文件长度存入Zone[][]数组中,并进行Clean() ,Sort()函数,整理和排序。

好吧感觉写的差不多了。

其他函数

感觉其他函数没有什么好说的,主要是一些字符串操作和文件操作,文件要和源文件放在同一文件夹下。否则要给出路径。

好吧这次课设,因为Zhai老师的认真负责还是学到了很多东西,不过课设安排的有些浪费时间,少了好多复习时间,考试还要努力啊,

以上就是本人这次代码的拙见,各位大佬,若是发现什么问题或者什么错误,或者要一起探讨一下代码,欢迎评论。


而且,19周考试要考4门,周一概率论,周N操作系统,我的天,就剩下两天的复习时间,一个垃圾课设居然这么拖拖拉拉,肝疼。呵呵,老师在平台上就不大声说话了,明天去验收,我真想WTM,

收获和感悟记得要更!!!!!!!!!!!!!!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章