📄 block.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 + -