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

📄 test2.cpp

📁 在Linux Red Hat下用C++设计并实现一个多用户多级目录结构的文件系统。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//读指定文件的信息
	if(offset/bsize<0||offset/bsize>=263||offset>fp->f_fsize-1)
	{
		cout<<"FCB READ ERROR\n";
		return FCBREADERR;
	}
	int temp=0;
	char buf[bsize+1];
	int num;
	if((fp->f_fsize-(offset+1)+1)>count)
		num=count;
	else
		num=fp->f_fsize-(offset+1)+1;
	for(int i=0;;i++)
	{
		if(iblock.bread(getblock(fp,(offset/bsize)+i),buf)==BLKREADERR)
		{
			cout<<"BLOCK READ ERROR\n";
			return BLKREADERR;
		}
		if(i==0)
			temp=0;
		else
			if(i==1)
				temp=bsize-offset%bsize;
			else
				temp=bsize-offset%bsize+bsize*(i-1);
		if(num-(bsize-offset%bsize)>=0&&i==0)
		{
			for(int k=0;k<(bsize-offset%bsize);k++)
				base[k]=buf[offset%bsize+k];
			base[bsize-offset%bsize]='\0';
		}
		else
		{
			if((num-(bsize-offset%bsize)-i*bsize)<0)
			{
				for(int j=temp;j<num;j++)
				{
					if(i==0)
						base[j]=buf[j-temp+offset%bsize];
					else
						base[j]=buf[j-temp];
             
				}
				base[num]='\0';
				fp->f_count++;
				return num;
			}
			else
				strcat(base,buf);
		}
   }
}
int ifcb::writei(fcb *fp,int offset,int count,char*base)
{
	if(offset>fp->f_fsize||offset<0)
	{
		cout<<"FCB WRITE ERROR\n";
		return FCBWRITEERR;
	}
	if((offset+count-1)/bsize>=263)
	{
		cout<<"NOT ENOUGH SPACE\n";
		return NOSPACE;
	}   
 //写信息入指定的文件
	int temp=0;
	char buf[bsize+1];
	int ph=-1;
	int blkno;
	for(int i=0;;i++)
	{
		if(i==0)
			temp=0;
		else
			if(i==1)
				temp=bsize-offset%bsize;
			else
				temp=bsize-offset%bsize+bsize*(i-1);
		if(ph==0)
		{
			blkno=iblock.balloc();
			if(blkno==NOSPACE||blkno==BLOCKERR)
			{
				cout<<"FCB WRITE ERROR\n";
				return blkno;
			}
			addblock(fp,blkno);
		}
		else
		{
			ph=getblock(fp,offset/bsize+i);
			if(ph==0)
			{
				blkno=iblock.balloc();
				if(blkno==NOSPACE||blkno==BLOCKERR)
				{
					cout<<"FCB WRITE ERROR\n";
					return blkno;
				}
				addblock(fp,blkno);
			}
			else
			{
				blkno=ph;
				if(i==0)
				{
					if(iblock.bread(blkno,buf)==BLKREADERR)
					{
						cout<<"FCB WRITE ERROR\n";
						return BLKREADERR;
					}
				}
			}
		}
		if(count-(bsize-offset%bsize)>0&&i==0)
		{
			for(int k=0;k<(bsize-offset%bsize);k++)
				buf[offset%bsize+k]=base[k];
			if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
			{
				cout<<"FCB WRITE ERROR\n";
				return BLKWRITEERR;
			}
		}
		else
		{
			if((count-(bsize-offset%bsize)-i*bsize)<=0)
			{                                                                  
				for(int j=temp;j<count;j++)
				{
					if(i==0)
						buf[offset%bsize+j-temp]=base[j];
					else
						buf[j-temp]=base[j];                                                                             
				}
				if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
				{
					cout<<"FCB WRITE ERROR\n";
					return BLKWRITEERR;
				}
				if((offset+count-1)/bsize<(fp->f_fsize-1)/bsize)
				{
					for(int tt=((offset+count-1)/bsize)+1;tt<=(fp->f_fsize-1)/bsize;tt++)
					{
						iblock.brelse(getblock(fp,tt));
					}
				}    
				fp->f_fsize=offset+count;
				if(fp->f_flag<FCHG)
					fp->f_flag=fp->f_flag|FCHG;
				fp->f_count++;
				return count;
			}
			else
			{
				for(int t=temp;t<temp+bsize;t++)
				{
					buf[t-temp]=base[t];
				}
				if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
				{
					cout<<"FCB WRITE ERROR\n";
					return BLKWRITEERR;
				}
			}
		}
	}
} 
fcb *ifcb::iget(int blkno,int num)
{
//读出指定的文件目录结构的信息,并产生对应的FCB结构
	int free=0;
	for(;free<16;free++) //寻找FCB系统中空闲的位置
	{
		if(fcbi[free]==NULL)
        break;
	}
	if(free>=16)
	{
		cout<<"FCB STRUCT IS FULL\n";
		return NULL;
	}
	char buf[bsize+1];
	if(iblock.bread(blkno,buf)==BLKREADERR)
	{
		cout<<"CREATE FCB ERROR\n";
		return NULL;
	}
	fcbi[free]=new struct fcb;//产生fcb结构并初始化
	fcbi[free]->f_mode=int((unsigned char)buf[num*dsize])*256+int((unsigned char)buf[num*dsize+1]);
	fcbi[free]->f_uid=buf[num*dsize+2];
	fcbi[free]->f_gid=buf[num*dsize+3];
	fcbi[free]->f_fsize=int((unsigned char)buf[num*dsize+4])*16777216+int((unsigned char)buf[num*dsize+5])*65537+int((unsigned char)buf[num*dsize+6])*256+int((unsigned char)buf[num*dsize+7]);
	for(int n=0;n<8;n++)
	{
		fcbi[free]->f_name[n]=buf[num*dsize+8+n];
	}
	for(int a=0;a<8;a++)
	{
		fcbi[free]->f_add[a]=int((unsigned char)buf[num*dsize+16+a*2])*256+int((unsigned char)buf[num*dsize+16+a*2+1]);
	}
	fcbi[free]->f_blkno=blkno;
	fcbi[free]->f_number=num;
	fcbi[free]->f_count=1;
	fcbi[free]->f_flag=FLOCK;
	fcbnum++;
	return fcbi[free];
}
int ifcb::iput(fcb *fp)
{
	if(fp->f_flag>=FCHG) //fcb结构信息有改变,则存储该fcb的信息到文件目录结构中
	{
		char buf[bsize+1];
		if(iblock.bread(fp->f_blkno,buf)==BLKREADERR)
		{
			cout<<"SAVE FCB ERROR\n";
			return BLKREADERR;
		}
		buf[fp->f_number*dsize]=char(fp->f_mode/256);
		buf[fp->f_number*dsize+1]=char(fp->f_mode%256);
		buf[fp->f_number*dsize+2]=fp->f_uid;
		buf[fp->f_number*dsize+3]=fp->f_gid;
		buf[fp->f_number*dsize+4]=char(fp->f_fsize/16777216);
		buf[fp->f_number*dsize+5]=char((fp->f_fsize%16777216)/65536);
		buf[fp->f_number*dsize+6]=char(((fp->f_fsize%16777216)%65536)/256);
		buf[fp->f_number*dsize+7]=char(((fp->f_fsize%16777216)%65536)%256);
		for(int n=0;n<8;n++)
		{
			buf[fp->f_number*dsize+8+n]=fp->f_name[n];
		}
		for(int a=0;a<8;a++)
		{
			buf[fp->f_number*dsize+16+a*2]=char(fp->f_add[a]/256);
			buf[fp->f_number*dsize+16+a*2+1]=char(fp->f_add[a]%256);
		}
		if(iblock.bwrite(fp->f_blkno,buf)==BLKWRITEERR)
		{
			cout<<"SAVE FCB ERROR\n";
			return BLKWRITEERR;
		}
	}
//删除FCB系统中对应的fcb
	for(int w=0;w<16;w++)
	{
		if(fp==fcbi[w])
		{
			fcbi[w]=NULL;
			delete fp;
			break;
		}
	}
	fcbnum--;
	return OK;
}
fcb *ifcb::namei(fcb *fp,char*name,int f_mode)
{
//在FCB系统中查找,fp==NULL是查找根目录
	for(int it=0;it<fcbmax;it++)
	{
		if(fcbi[it]!=NULL)
		{
			if(strcmp(fcbi[it]->f_name,name)==0)
			{
				if(fp==NULL&&fcbi[it]->f_blkno==0)
					return fcbi[it];
				int u;
				for(int yy=0;yy<263;yy++)
				{
					u=getblock(fp,yy);
					if(u==0)
						break;
					else
					{
						if(u==fcbi[it]->f_blkno)
						{  
							if((fcbi[it]->f_mode==IFDIR&&f_mode==IFDIR)||(fcbi[it]->f_mode>=IFREG&&f_mode>=IFREG))
								return fcbi[it];
						}
					} 
				}
			}
		}
	}
//在指定的FCB对应的空间中查找
	char buf[bsize+1];
	char f_name[8];
	int d_mode;
	if(fp==NULL)
	{
		iblock.bread(0,buf);
		for(int g=0;g<8;g++)
		{
			f_name[g]=buf[dsize*15+8+g];
		}
		d_mode=int((unsigned char)buf[dsize*15])*256+int((unsigned char)buf[dsize*15+1]);
		if(strcmp(name,f_name)==0)
		{
			if((d_mode==IFDIR&&f_mode==IFDIR)||(d_mode>=IFREG&&f_mode>=IFREG))
				return iget(0,15);
		}
		return NULL;
	}
	int blkno;
	int blkend;
	int dirend;
	blkend=(fp->f_fsize-1)/bsize;
	dirend=((fp->f_fsize-1)%bsize)/dsize;
	for(int i=0;i<263;i++)
	{
		if(i==(blkend+1))
			return NULL;
		blkno=getblock(fp,i);
		if(blkno==0)
			return NULL;
		if(iblock.bread(blkno,buf)==BLKREADERR)
			return NULL;
		for(int d=0;d<16;d++)
		{
			if(i==blkend&&d==(dirend+1))
				return NULL;
			for(int n=0;n<8;n++)
			{
				f_name[n]=buf[dsize*d+8+n];
			}
			d_mode=int((unsigned char)buf[dsize*d])*256+int((unsigned char)buf[dsize*d+1]);
			if(strcmp(f_name,name)==0)
			{
				if((d_mode==IFDIR&&f_mode==IFDIR)||(d_mode>=IFREG&&f_mode>=IFREG))
					return iget(blkno,d);
			}
		}
	}
	return NULL;
}
fcb *ifcb::icreate(fcb *fp,char*name)
{
//在指定的fcb下创建fcb,fp==NULL,是创建根目录
	int i=0;
	for(;i<fcbmax;i++)
	{
		if(fcbi[i]==NULL)
			break;
	}
	if(i>=fcbmax)
		return NULL;
	fcb *ft=new struct fcb;
	int blkno;
	int num;
	if(fp==NULL)
	{
		blkno=0;
		num=15;
		ft->f_uid='0';
		ft->f_gid='0';
	}
	else
	{
		if(fp->f_fsize==0||(fp->f_fsize-1)%bsize==511)
		{
			blkno=iblock.balloc();
			addblock(fp,blkno);
			num=0;
		}
		else
		{
			blkno=getblock(fp,(fp->f_fsize-1)/bsize);
			num=(((fp->f_fsize-1)%bsize)/dsize)+1;
		}
		fp->f_fsize=fp->f_fsize+32;
		fp->f_flag=FUPD|FCHG;
	}
	ft->f_count=1;
    ft->f_flag=FCHG;
    ft->f_blkno=blkno;
    ft->f_number=num;
    ft->f_mode=IFMT;
    ft->f_fsize=0;
    strcpy(ft->f_name,name);
    for(int a=0;a<8;a++)
    {
       ft->f_add[a]=0;
    }
    fcbi[i]=ft;
    fcbnum++;
    return ft;
} 
int ifcb::idelete(fcb *pfp,fcb *fp)
{
//删除父目录中,该文件目录的信息
	for(int yy=0;yy<263;yy++)
	{
		if(getblock(pfp,yy)==fp->f_blkno)
		{
			char*base;
			if(yy*bsize+fp->f_number*dsize+32>pfp->f_fsize-1)
			{
				base=new char[pfp->f_fsize-32+1];
				readi(pfp,0,pfp->f_fsize-32,base);
				writei(pfp,0,pfp->f_fsize-32,base);
			}
			else
			{
				base=new char[pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1+1];
readi(pfp,yy*bsize+fp->f_number*dsize+32,pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1,base);		writei(pfp,yy*bsize+fp->f_number*dsize,pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1,base);        
			}
			if(pfp->f_flag<FCHG)
				pfp->f_flag=pfp->f_flag|FCHG;
			delete[]base;
			break;
		}
	}
//删除该FCB对应的文件,释放空间
	int g;     
	for(int kk=0;kk<263;kk++)
	{
		g=getblock(fp,kk);
		if(g==0)
			break;
		else
			iblock.brelse(g);
	}
	if(curfp==fp)
		curfp=NULL;
	for(int ee=0;ee<fcbmax;ee++)
	{
		if(fcbi[ee]==fp)
		{
			fcbi[ee]=NULL;
			fcbnum--;
			delete fp;
		}
	}
	return OK;
}

#define fcbmax 16
#define dsize 32
struct fcb			//FCB结构
{
	char f_count;	//文件访问次数
	char f_flag;	//标志字
	int f_blkno;	//存放本文件目录结构的块号
	int f_number;	//文件目录结构所在块内偏移序号
	unsigned short f_mode;	//文件属性
	char f_uid;		//文件主ID
	char f_gid;		//同主用户ID
	int f_fsize;	//文件大小
	char f_name[8]; //文件名
	unsigned short int f_add[8];		//存放文件信息的空间地址
};
class ifcb
{
public:
	ifcb();
	int readi(fcb *fp,int offset,int count,char*base);	//读指定FCB所代表的文件
	int writei(fcb *fp,int offset,int count,char*base);	//写指定FCB所代表的文件
	int getblock(fcb *fp,int lblock);	//得到指定文件的指定逻辑块所对应的物理块
	int addblock(fcb *fp,int pblock);	//将物理块加到指定文件中,增加空间
	int getiadd(fcb *fp);				//得到指定文件的一级间接寻址的的块信息
	int putiadd(fcb *fp);				//将指定文件的一级间接寻址的块信息写入
	fcb *iget(int blkno,int num);		//读出指定的文件目录结构,并产生对应的FCB
	int iput(fcb *fp);					//将FCB的信息存入对应的文件目录结构中
	fcb *icreate(fcb *fp,char*name);	//在指定FCB下,创建FCB
	int idelete(fcb *pfp,fcb *fp);		//在指定FCB下,删除指定FCB
	fcb *namei(fcb *fp,char*name,int f_mode=IFREG);		//文件查找
	~ifcb();
private:
	unsigned short int iadd[256];		//存储一级间接寻址的信息
	struct fcb *curfp;					//当前在运行的FCB
	struct fcb *fcbi[fcbmax];			//FCB系统
	int fcbnum;							//当前FCB系统中FCB的数目
	class block iblock;					//嵌套块管理层
};

#define FLOCK 01  //FCB访问互斥标志
#define FUPD 02   //本FCB代表的文件已经修改
#define FCHG 04   //本FCB结构中某些信息已经被修改

extern int vp;  //文件卷的文件描述字
//extern int first;

⌨️ 快捷键说明

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