⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2.cpp

📁 模拟采用二级目录结构的磁盘文件系统中文件操作
💻 CPP
字号:
//该程序在Windows 2000+Visual C++下调试通过
#include <time.h>
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
const int N  = 2;	//用户数
const int L  = 6;	//用户最多文件数
const int S  = 3;	//用户最多打开文件数
const int cp = 3;   //每个文件的最多可用磁盘块数

struct FileRecord	//文件分配表记录
{
	bool Empty;
	int  Next;
};

FileRecord FileRecords[N*L*cp];	     //文件记录的总空间n*l*cp

enum Fileatt		 //文件属性
{
	ReadOnly=0,      //只读设为0
	ReadWrite=1      //可读可写设为1
};

enum FileStats	     //文件状态
{
	OpenStats=0,
	CreateStats=1
};

class mfd			 //主文件目录
{
public:
	mfd()
	{
		UserCount=0;     //用户数
		CurUser=-1;		 //当前用户指针即没有用户
	}

	struct UserDir       //用户目录
	{
		char Name[20];
		int  DirAdd;
	};

	UserDir myUserDir[N];//定义主文件目录数组变量
	
	int UserCount;
	int CurUser;         //从0开始

public:

	int SearchName(char *UserName)	//查找用户,返回用户指针

	{
		for(int i=0;i<UserCount;i++)
		{
			if(!strcmp(UserName,myUserDir[i].Name))
			{
				CurUser=i;
				return(CurUser);
			}
		}
		return(-1);
	}
};

class ufd			       //用户文件目录 
{
	public:
	int FileCount;
    ufd()
	{
		FileCount=0;		//用户文件数
	}

	struct FileDir
	{
		char FileName[8];
		Fileatt att;
		int RecLen;
		int FileAdd;
	};

	FileDir FileDirs[L];     //定义用户文件目录数组变量 
	
	int Set(char *FileName,int RecLen,Fileatt att)//设置用户文件目录
	{
		FileCount ++;
		strcpy(FileDirs[FileCount-1].FileName,FileName);//向数组内赋值
		FileDirs[FileCount-1].RecLen=RecLen;
		FileDirs[FileCount-1].att=att;
		return(FileCount-1);
	}

	int SearchFile(char *FileName)    //查找用户文件
	{
		for(int i=0;i<FileCount;i++)
		{
			if(!strcmp(FileName,FileDirs[i].FileName))
			{
				return(i);
			}
		}
		return(-1);
	}
};

class uof //用户打开文件表
{
public:

	uof()
	{
		openFileDirCount=0;	//打开文件数
	}

	struct openFileDir
	{
		char FileName[8];
		Fileatt att;
		int RecLen;
		FileStats Stats;
		int ReadAdd;
		int WriteAdd;
	};

	openFileDir openFileDirs[S];      //定义打开用户文件目录数组变量

	int openFileDirCount;

	int SearchFile(char *FileName)//查找用户打开文件
	{
		for(int i=0;i<openFileDirCount;i++)
		{
			if(!strcmp(FileName,openFileDirs[i].FileName))
			{
				return(i);
			}
		}
		return(-1);
	}


	int Set(char *FileName,int RecLen,Fileatt att)//设置用户打开文件目录
	{
		openFileDirCount++;
		strcpy(openFileDirs[openFileDirCount-1].FileName,FileName);
		openFileDirs[openFileDirCount-1].RecLen=RecLen;
		openFileDirs[openFileDirCount-1].att=att;
		return(openFileDirCount-1);
	}
};



class Zhko		//主控类
{
public:
	mfd *mymfd;		    //主文件目录
	ufd *myufds;		//用户文件目录数组
	uof *myuofs;		//用户打开文件表数组

	static void SetNotEmpty(int i)  //设置一个空间已占用不为空
	{
		FileRecords[i].Empty=false;
	}
	Zhko(mfd *mfd,ufd *ufds,uof *uofs)
		//主控类构造函数
	{
		mymfd=mfd;
		myufds=ufds;
		myuofs=uofs;

		srand((unsigned)time(NULL));	   //初始化随机函数

		for(int i=0;i<N*L*cp;i++)          //初始化文件分配表
		{
			FileRecords[i].Empty=true;
			FileRecords[i].Next=NULL;
		}	
	}

	void NewList(ufd *myufds,uof *myuof)//新建链表即初始化时分配空间
	{
		int X=myufds->FileCount;
		int Y=myuof->openFileDirCount;

		int i=rand()%(N*L*cp);			//随机模拟分配
		while(!FileRecords[i].Empty)    //空间占用
			i=rand()%(N*L*cp);
		FileRecords[i].Empty=false;     //分配后做标记
		FileRecords[i].Next=NULL;

		myufds->FileDirs[X-1]. FileAdd=i;
		myuof->openFileDirs[Y-1].Stats=CreateStats;
		myuof->openFileDirs[Y-1].WriteAdd=i;
		myuof->openFileDirs[Y-1].ReadAdd=i;
	}
	
	void AddList(uof *myuof)			//分配增加链表
	{
		int count=myuof->openFileDirCount;

		int Add=myuof->openFileDirs[count-1].WriteAdd;
		cout<<"Write "<<Add<<endl;

		int i=rand()%(N*L*cp);			//随机模拟分配
		while(!FileRecords[i].Empty)
			i=rand()%(N*L*cp);
		FileRecords[i].Empty=false;
		FileRecords[Add].Next=i;

		FileRecords[i].Next=NULL;
		myuof->openFileDirs[count-1].WriteAdd=i;
		myuof->openFileDirs[count-1].ReadAdd=i;

	}	

	//建立文件函数
	int Create(char *FileName,int RecLen,Fileatt att)
	{
		int CurUser=mymfd->CurUser;
		if(myufds[CurUser].SearchFile(FileName)!=-1)//调用SEARCH函数找不到则为-1
			//如果UFD中有同名文件
		{
			cout<<"错误!同名文件不能建立!"<<endl;
			return(0);
		}
		else		//如果UFD中没有同名文件
		{
			if(myufds[CurUser].FileCount>=L || myuofs[CurUser].openFileDirCount>=S)
			{
				cout<<"在UFD或UOF中找不到空登记栏"<<endl;
				return(0);
			}
			myufds[CurUser].Set(FileName,RecLen,att);
			myuofs[CurUser].Set(FileName,RecLen,att);

			NewList(&myufds[CurUser],&myuofs[CurUser]);//分配磁空间

			cout<<"文件创建成功!"<<endl;
			return(1);
		}
	}

	//打开文件函数
	int Open(char *FileName,Fileatt att)
	{
		int iufds,iuofs;  //当前文件在用户文件目录和打开文件表中的指针

		int CurUser=mymfd->CurUser;

		iufds=myufds[CurUser].SearchFile(FileName);
		iuofs=myuofs[CurUser].SearchFile(FileName);

		if(iufds==-1) //UFD中没有该文件
		{
			cout<<"文件不存在,不能打开!"<<endl;
			return(0);
		}
		
		if(iuofs!=-1)//UFD中有该文件,UOF中有该文件
		{
			if(myuofs[CurUser].openFileDirs[iuofs].Stats==CreateStats)
				//该文件为建立状态
			{
				cout<<"正在建立不能打开!"<<endl;
				return(0);
			}
			else
			{
				cout<<"错误!文件已打开!"<<endl;
				return(1);
			}
		}
		else //UFD中有该文件,UOF中没有该文件
		{
			if(myufds[CurUser].FileDirs[iufds].att!=att)
			{
				cout<<"操作(读写属性)不合法,不能打开!"<<endl;
				return(0);
			}
			else	//类型相符,登记
			{
	
				int i=myuofs[CurUser].Set(FileName,myufds[CurUser].FileDirs[iufds].RecLen,att);	
				myuofs[CurUser].openFileDirs[i].Stats=OpenStats;
				int Add=myufds[CurUser].FileDirs[iufds].FileAdd;
				myuofs[CurUser].openFileDirs[i].ReadAdd=Add;
				myuofs[CurUser].openFileDirs[i].WriteAdd=Add;
				cout<<"打开成功!"<<endl;
				return(1);
			}
		}
	}

	//关闭文件函数
	int Close(char *FileName)
	{	
		//查用户的用户已开文件表(UFO)
		int iufds,iuofs;
		int CurUser=mymfd->CurUser;

		iuofs=myuofs[CurUser].SearchFile(FileName);
		iufds=myufds[CurUser].SearchFile(FileName);
		if(iuofs==-1)		//如果UOF中没有该文件
		{
			cout<<"错误,该文件未曾打开!"<<endl;
			return(0);
		}
		if(myuofs[CurUser].openFileDirs[iuofs].Stats==CreateStats)
			//文件状态为"建立"
		{
			//置文件结束标志
		}	
		int count=myuofs[CurUser].openFileDirCount;
		for(int i=iuofs;i<count;i++)		//消除登记栏
			myuofs[CurUser].openFileDirs[i]=myuofs[CurUser].openFileDirs[i+1];
		myuofs[CurUser].openFileDirCount--;
		cout<<"文件成功关闭!"<<endl;
		return(1);
	}
};	

//初始化
void init(mfd *mymfd,ufd *myufds,uof *myuofs)
{
	//初始化主文件目录
	strcpy(mymfd->myUserDir[0].Name,"xu");
	mymfd->myUserDir[0].DirAdd=0;
	strcpy(mymfd->myUserDir[1].Name,"kd");
	mymfd->myUserDir[1].DirAdd=0;
	mymfd->UserCount=2;
	mymfd->CurUser=0;

	//初始化用户文件目录
	int i=rand()%(N*L*cp);
	Zhko::SetNotEmpty(i);
	strcpy(myufds[0].FileDirs[0].FileName,"userfile");
	myufds[0].FileDirs[0].RecLen=10;
	myufds[0].FileDirs[0].FileAdd=i;
	myufds[0].FileDirs[0].att=ReadOnly;
	myufds[0].FileCount=1;

	//初始化打开用户文件表
	strcpy(myuofs[0].openFileDirs[0].FileName,"userfile");
	myuofs[0].openFileDirs[0].att=ReadOnly;
	myuofs[0].openFileDirs[0].ReadAdd=i;
	myuofs[0].openFileDirs[0].WriteAdd=i;
	myuofs[0].openFileDirs[0].Stats=OpenStats;
	myuofs[0].openFileDirs[0].RecLen=10;
	myuofs[0].openFileDirCount=1;	
}

void main()
{
	char UserName[20];
	char Command;
	char FileName[20];
	int RecLen;
	Fileatt att;
	char choice;

	mfd mymfd;
	ufd myufds[N];
	uof myuofs[N];

	Zhko myZhko(&mymfd,myufds,myuofs);

	//初始化
	init(&mymfd,myufds,myuofs);

	begin:

	do
	{
		cout<<"请输入用户名(xu或kd):"<<endl;
		cin>>UserName;
		if(mymfd.SearchName(UserName)==-1)  //用户名不对
		{
			cout<<"非法用户!"<<endl;
		    continue;
		}

		cout<<"请输入你要的操作:"
			<<"c-创建 o-打开 g-关闭 q-结束"<<endl;
		cin>>Command;
		switch(Command)
		{
		case 'c'://建立文件
			{
				cout<<"请输入文件名字:"<<endl;
				cin>>FileName;
				cout<<"请输入记录长度:"<<endl;
				cin>>RecLen;

				INPUT:

				cout<<"请输入文件属性:"
					<<"(0-ReadOnly,1-ReadWrite):"<<endl;
				cin>>choice;
				switch(choice)
				{
				case '0':
					att=ReadOnly;
					break;
				case '1':
					att=ReadWrite;
					break;
				default:
					cout<<"错误,请重新输入!"<<endl;
					goto INPUT;
				}
				myZhko.Create(FileName,RecLen,att);
			}
			break;
		case 'o':	//打开文件
			{
				cout<<"请输入文件名字:"<<endl;
				cin>>FileName;
	INPUTs:
				cout<<"请输入文件属性:"
					<<"(0-ReadOnly,1-ReadWrite):"<<endl;
				cin>>choice;
				switch(choice)
				{
				case '0':
					att=ReadOnly;
					break;
				case '1':
					att=ReadWrite;
					break;
				default:
					cout<<"错误,请重新输入!"<<endl;
					goto INPUTs;
				}
				myZhko.Open(FileName,att);
			}
			break;
		case 'g':		//关闭文件
			cout<<"请输入文件名字:"<<endl;
			cin>>FileName;
			myZhko.Close(FileName);
			break;
		case 'q':
			return;
			break;
		default:
			cout<<"错误命令!"<<endl;
			goto begin;
		}
	}while(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -