📄 test2.cpp
字号:
//读指定文件的信息
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 + -