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

📄 block.h

📁 文件管理系统
💻 H
字号:
#include<iostream>
#include<stdio.h>
#include<string>
#include<stdlib.h>
#include<bitset>
#include<iomanip>

using namespace std;

#define BLOCK 512
#define BLOCKNUM 2048
#define DN 8	
#define USERNUM 10	//最大用户数
#define FILENUM 9		//每个块能存储的文件目录结构数量

/*FCB标志字(f_flag)的各种标志定义为:*/
#define FLOCK 01	/*FCB访问互斥标志*/
#define FUPD  02	/*本FCB代表的文件已修改*/
#define FCHG  04	/*本FCB结构中某些信息已被修改*/
#define FCBFLAG 05  //本fcb结构未被使用
#define FCBUSE	07  //本fcb结构已被使用
#define OFFLAG 06  //本HOfile结构未被使用
#define OFUSE  03 //本HOfile结构已被使用

//文件属性及文件访问权限(即d_mode和f_mode)定义:
#define ROOT  111
#define IFROOT 011		//子目录中存储父目录的结构
#define IFMT  0070000	//文件类型屏蔽字
#define IFDIR 0010000	//子目录文件
#define IFREG 0020000	//普通文件
#define IREAD 0400		//文件主”读"权限
#define IWRITE 0200		//文件主“写”权限
#define IEXEC 0100		//文件主“执行”权限
#define GREAD 040		//同组用户“读”权限
#define GWRITE 020		//同组用户“写”权限
#define GEXEC 010		//同组用户“执行”权限
#define OREAD 04		//其它用户“读”权限
#define OWRITE 02		//其它用户“写”权限
#define OEXEC 01		//其它用户“执行”权限
#define NONODE 100



inline int bit_on(unsigned char ui,int pos){return ui&(1<<pos);}//"1"返回true
inline void bit_setone(unsigned char& ui,int pos){ui|=1<<pos;}
inline void bit_setzero(unsigned char& ui,int pos){ui&=~(1<<pos);}

struct USERINFO//注册用户信息
{
	char d_flag;	//标识该用户信息是否有效,超级用户为用户数目,-1表示无效
	char d_uid;     /*用户标识,为0时表示是超级*/
	char d_gid;     /*同组用户标识*/
	char d_name[8];/*用户名,但不超过八个字节,超过八位自动截取*/
	char password[8];/*用户密码但不超过八位,超过八位自动截取*/
};

struct dir
{
	unsigned short d_mode; //文件属性及访问权限,<=0时为空结构
	char d_uid;			   //文件主标识
	char d_gid;				//文件主同组用户标识
	int d_fsize;			//文件大小(字节),作为目录结构时为该目录下文件个数
	char d_name[8];			//文件名
	int d_add[10];			//存放文件信息的空间地址(块号)
};

struct SFcb
{
	char f_count;	/*文件访问计数*/
	char f_flag;	/*标志字*/
	int  f_blkno;	/*存放本文件目录结构的块号*/
	int f_number;	/*文件目录结构所在块内偏移序号*/
	unsigned short f_mode; /*文件属性*/
/*以下各项信息在文件打开时从struct dir获取*/
	char f_uid;
	char f_gid;
	int  f_fsize;
	char f_name[8];
	int  f_add[10];
};

struct Hfcb//用于Namei函数,返回文件目录结构存储位置
{
	int blkno;			//存放本文件目录结构的块号
	int offset;		//文件目录结构所在块内偏移序号
};

#define FCBMAX  16
struct SFcb tfcb[FCBMAX];   //系统fcb[]结构



struct HOFile
{
	char o_flag;					//标志字
	int o_count;					//访问计数
	struct SFcb* o_fcbp;				//对就打开文件FCB结构指针
	int o_offset;					//文件当前读/写指针
};
#define FILENO 10
struct HOFile ofile[FILENO];	//系统打开文件表ofile
void InitOFile()//初始化ofile数组
{
	for(int i=0;i<FILENO;i++)
		ofile[i].o_flag=OFFLAG;
}


struct TUser
{
	char u_name[8];	//用户名,登录时使用
	char u_uid;			//用户标识,文件创建时的文件主
	char u_gid;			//同组用户标识
	struct SFcb *u_cdir;	//现行工作目录标识
	int u_error;		//执行文件管理函数时返回的错误代码,创建文件时被用来存储文件设置
	char*u_base;		//读/写文件时信息存储区始址
	int u_count;		//读/写文件时信息字节数
	int u_offset;		//读/写文件的相对位移量
	char u_obuf[8];		//文件路径名分量暂存区(查找文件时用)
	struct SFcb* u_pdir;	//新文件父目录FCB指针(文件创建时用)
	struct HOFile *u_ofile[5];//本用户打开文件表
};

int fun=0;
#define USERNO 5
struct TUser user[USERNO];
void InitUser()//初始化用户数组
{
	for(int uof=0;uof<USERNO;uof++)
		for(int of=0;of<5;of++)
			user[uof].u_ofile[of]=NULL;
}


class TBlock
{
public:
	TBlock();							//
	~TBlock();
	int Balloc();						//块分配函数
	void Brelse(int bno);				//块释放函数
	bool Bread(int bno,char* tempbuf);	//读一块函数
	void CheckFirst();					//检查是否是第一次
	void CreateFile(USERINFO info);		//创建文件(模拟文件系统的硬盘空间)
	void CreateList(int bno,dir& tempdir);			//创建子目录
	void FirstInit(USERINFO info);		//第一次进入系统时的初始化
	void Init();						//正常初化
	bool IsFirst();						//返回first的值
	bool BWrite(int bno,char* tempbuf);	//写一块函数
	void SaveInfo();					//对读入内存的0#块内容,写入硬盘
	void SetFirst();					//将first置为true即,不是第一次启动
protected:
	unsigned char bitmap[256];
	FILE* pf;
	bool first;
	char* buf;
	dir rootdir;
};


TBlock::TBlock()
{
	InitUser();//初始化用户数组,以备用户登陆时用
	pf=NULL;
	first=false;
	if((buf=new char[512])==NULL)
	{
		cout<<"内存不足"<<endl;
		exit(0);
	}
	CheckFirst();//检查是不是用户第一次启动系统
	if(first==false)
	{
		Init();//如果不是第一次登陆,则进入用户登陆界面
	}

}

TBlock::~TBlock()
{
	
	SaveInfo();
	delete[]buf;
	fclose(pf);
}

int TBlock::Balloc()//块分配函数
{
	int bit,byte,i=0,count=1;
	for(;i<2048;i++)//设置位示图
	{
		count++;
		if(count>2048)
			break;
		bit=i%DN;
		byte=(i-bit)/DN;
		if(bit_on(bitmap[byte],bit)==1)
			continue;
		else
		{
			bit_setone(bitmap[byte],bit);
			char* tempbuf=NULL;
			if((tempbuf=new char[BLOCK])==NULL)
			{
				cout<<"内存不足!"<<endl;
				return -1;
			}
			BWrite(i,tempbuf);
			delete[]tempbuf;
			return i;
		}
		if(i>=2048)
			i=i%2048;
	}
	return -1;
}

void TBlock::Brelse(int bno)//释放块
{
	int byte,bit;
	bit=bno%DN;
	byte=(bno-bit)/DN;
	bit_setzero(bitmap[byte],bit);
	char* tempbuf=NULL;
	tempbuf=new char[BLOCK];
	for(int i=0;i<BLOCK;i++)
		tempbuf[i]='\0';
	fseek(pf,bno*BLOCK,SEEK_SET);
	fwrite(tempbuf,sizeof(char),BLOCK,pf);
	delete[]tempbuf;
}

bool TBlock::Bread(int bno,char* tempbuf)//读块函数
{
//	a=false;
	int byte,bit;
	if(bno>=2048)
		return false;
	bit=bno%DN;
	byte=(bno-bit)/DN;
	if(bit_on(bitmap[byte],bit)==1)
	{
		
		fseek(pf,(long)(bno*BLOCK),SEEK_SET);
		fread(tempbuf,sizeof(char),BLOCK,pf);
		
		return true;
	}
	else
		return false;
}

bool TBlock::BWrite(int bno,char* tempbuf)//写块函数
{
	if(bno>=2048||tempbuf==NULL)
		return false;
	int byte,bit;
	bit=bno%DN;
	byte=(bno-bit)/DN;
	if(bit_on(bitmap[byte],bit)==false)
		return false;
	else
	{
		fseek(pf,bno*BLOCK,SEEK_SET);
		fwrite(tempbuf,sizeof(char),BLOCK,pf);
		return true;
	}
}

void TBlock::CheckFirst()//检查存在操作文件,即模拟磁盘空间的文件,以判断是否是第一次启动系统
{
	if((pf=fopen("storage","r"))==NULL)
		TBlock::first=true;
	else
		fclose(pf);
}

void TBlock::CreateFile(USERINFO info)//创建模拟磁盘的文件
{
	if((pf=fopen("storage","w+"))==NULL)
	{
		cout<<"创建文件失败"<<endl;
		exit(0);
	}
	char* tempbuf;
	if((tempbuf=new char[512])==NULL)
	{
		cout<<"内存不足"<<endl;
		exit(0);
	}
	int i;
	for(i=0;i<BLOCK;i++)
		tempbuf[i]='\0';
	fseek(pf,0,SEEK_SET);
	for(i=0;i<BLOCKNUM;i++)					//创建文件
		fwrite(tempbuf,sizeof(char),BLOCK,pf);
	delete[]tempbuf;
}

void TBlock::CreateList(int bno,dir& tempdir)//创建目录
{
	char* tchar;
	dir* tdir=NULL;
	if((tchar=new char[512])==NULL)
	{
		cout<<"内存不足"<<endl;
		exit(0);
	}
	int i=0;
	for(i=0;i<BLOCK;i++)
		tchar[i]='\0';
	tdir=(dir*)(tchar);
	tdir->d_fsize=BLOCK-sizeof(dir);//根目录结构的块内存储偏移地址
	tdir->d_gid=tempdir.d_gid;
	tdir->d_uid=tempdir.d_uid;
	tdir->d_mode=tempdir.d_mode;
	int na;
	for(na=0;na<8;na++)
		tdir->d_name[na]=tempdir.d_name[na];
	for(i=0;i<10;i++)
	{
		tdir->d_add[i]=tempdir.d_add[i];
	}
	tdir->d_add[0]=0;
	for(i=1;i<FILENUM;i++)
	{
		tdir=(dir*)(tchar+i*sizeof(dir));
		tdir->d_mode=NONODE;
	}
	BWrite(bno,tchar);
	delete[]tchar;
}

void TBlock::FirstInit(USERINFO info)//第一次初始化
{
	CreateFile(info);//创建模拟磁盘文件
	int i=0,byte,bit,j;
	for(i=0;i<512;i++)
		buf[i]='\0';
	for(i=0;i<2048;i++)
	{
		bit=i%DN;
		byte=(i-bit)/DN;
		bit_setzero(bitmap[byte],bit);
	}
	bit_setone(bitmap[0],0);//分配0#块
	int tempbno=Balloc();
	for(i=0;i<256;i++)		//将bitmap写入buf
	{
		buf[i]=(char)bitmap[i];
	}
	USERINFO temp;
	info.d_flag=1;
	info.d_uid=0;
	char* tempchar;
	tempchar=(char*)(&info);
	for(j=0;j<sizeof(USERINFO);j++,i++)//将超级用户信息写入buf
		buf[i]=tempchar[j];
	temp.d_flag=-1;//初始化将来将用于存储用户信息的空间
	tempchar=(char*)(&temp);
	for(byte=2;byte<=USERNUM;byte++)//已写入超级用户,所以应从第二个开始写
	{
		for(j=0;j<sizeof(USERINFO);j++,i++)
			buf[i]=tempchar[j];
	}

	dir tempdir;//初始化根目录结点
	tempdir.d_mode=IFROOT;
	tempdir.d_fsize=1;
	tempdir.d_uid=0;
	for(byte=0;byte<8;byte++)
		tempdir.d_add[byte]=-1;
	tempdir.d_name[0]='r';
	tempdir.d_name[1]='o';
	tempdir.d_name[2]='o';
	tempdir.d_name[3]='t';
	tempdir.d_name[4]='\0';
	tempdir.d_name[5]='\0';
	tempdir.d_name[6]='\0';
	tempdir.d_name[7]='\0';

	tempdir.d_add[0]=tempbno;

	tempchar=(char*)(&tempdir);
	i=BLOCK-sizeof(dir);
	for(byte=0;i<BLOCK;i++,byte++)//将根目录结构写入buf
		buf[i]=tempchar[byte];

	BWrite(0,buf);

	CreateList(tempdir.d_add[0],tempdir);//创建目录中的..目录

	SaveInfo();//保存位示图
}

void TBlock::Init()//用户登陆时的系统初始化
{
	if((pf=fopen("storage","r+"))==NULL)
	{
		cout<<"系统初始化失败"<<endl;
		exit(0);
	}
	fseek(pf,0,SEEK_SET);
	fread(buf,sizeof(char),BLOCK,pf);
	int i;
	for(i=0;i<256;i++)
		bitmap[i]=(unsigned char)buf[i];
}

bool TBlock::IsFirst()
{
	return first;
}

void TBlock::SaveInfo()//保存当前数据
{
	fseek(pf,0,SEEK_SET);
	fread(buf,sizeof(char),BLOCK,pf);
	for(int i=0;i<256;i++)
		buf[i]=(char)bitmap[i];
	BWrite(0,buf);
}

void TBlock::SetFirst()
{
	first=false;
}

⌨️ 快捷键说明

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