📄 main.cpp
字号:
#include"define.h"
/*******************************************************************************************
创建文件系统
*******************************************************************************************/
void Creat_System()
{ cout<<" ************************** WELCOME TO MY OS! **************************"<<endl;
cout<<" *************************************************************************"<<endl;
help();
int i,j;
fstream iof("C:\\LinuxOs.dat",ios::binary|ios::in|ios::out);//申请磁盘空间LinuxOs.dat
if(!iof)
{
cerr<<"磁盘空间无法创建!"<<endl;
return ;
}
iof.seekp(0,ios::beg); //申请空间,先将其都填充为" "
for(i=0;i<Block_Num*Block_Size;i++) //共申请Block_Num个磁盘块
{
iof.write(" ",sizeof(char));
}
iof.seekp(0,ios::beg); //填充超级块区
super.Free_Block=101867; //用于储存文件的磁盘块为101867块
super.Free_Inode=1023;
iof.write((char*)&super,sizeof(Super_Block));
iof.seekp(1016,ios::cur); //把文件的写指针从当前位置向后移1016个字节
for(i=0;i<Inode_Num;i++) //填充inode位图
{
if(i==0)
Inode_Bitmap[i]=1;
else Inode_Bitmap[i]=0;
iof.write((char*)&Inode_Bitmap[i],sizeof(int));
}
for(i=0;i<533;i++) //填充block位图,前533块已被占用
{
Block_Bitmap[i]=1;
iof.write((char*)&Block_Bitmap[i],sizeof(int));
}
for(i=533;i<Block_Num;i++) //后面的磁盘块都未被占用
{
Block_Bitmap[i]=0;
iof.write((char*)&Block_Bitmap[i],sizeof(int));
}
Inode[0].decide=0; //写根目录
strcpy(Inode[0].name,"L:"); //根目录命名为L盘
Inode[0].First_Block=-1; //根目录不额外占用磁盘块
Inode[0].length=0;
Inode[0].index=0;
Inode[0].parent=-1;
Inode[0].Child_Num=0; //子节点个数为0
for(j=0;j<15;j++) //将每个目录的子节点赋为-1
{
Inode[0].child[j]=-1;
}
GetLocalTime(&Inode[0].ctime); //获取当前系统时间
iof.write((char*)&Inode[0],sizeof(inode));
for(i=1;i<Inode_Num;i++) //填充Inode区
{
Inode[i].decide=-1;
Inode[i].index=i;
for(j=0;j<15;j++) //将每个目录的子节点赋为-1
{
Inode[i].child[j]=-1;
}
iof.write((char*)&Inode[i],sizeof(inode));
}
iof.close();
curr=0; //初始化当前目录为根目录
Curr_Inode=&Inode[curr];
strcpy(current,Curr_Inode->name);
strcat(current,"/");
}
/*******************************************************************************************
从磁盘中读取系统信息
*******************************************************************************************/
void Get_System_Info()
{
cout<<" ************************** WELCOME TO MY OS! **************************"<<endl;
cout<<" *************************************************************************"<<endl;
help();
fstream iof("C:\\LinuxOs.dat",ios::binary|ios::in|ios::out);//打开磁盘空间LinuxOs.dat
if(!iof)
{
cerr<<"磁盘空间无法打开!"<<endl;
return ;
}
int i;
iof.seekg(0,ios::beg);
iof.read((char*)&super,sizeof(Super_Block));
iof.seekg(1016,ios::cur);
for(i=0;i<Inode_Num;i++) //读取inode位图信息
{
iof.read((char*)&Inode_Bitmap[i],sizeof(int));
}
for(i=0;i<533;i++) //读取block位图信息
{
iof.read((char*)&Block_Bitmap[i],sizeof(int));
}
for(i=0;i<Inode_Num;i++) //读取Inode区信息
{
iof.read((char*)&Inode[i],sizeof(inode));
}
iof.close();
curr=0; //初始化当前目录为根目录
Curr_Inode=&Inode[curr];
strcpy(current,Curr_Inode->name);
strcat(current,"/");
}
/*******************************************************************************************
显示整个系统信息info命令
可显示已用磁盘空间,剩余磁盘空间,目录数目,文件数目
*******************************************************************************************/
void info()
{
int Free_Block_Size=(super.Free_Block)*Block_Size;//计算已用磁盘空间与空闲磁盘空间
int Used_Block_Size=(Block_Num-super.Free_Block)*Block_Size;
int File_Num=0;
int Dir_Num=0;
for(int index=0;index<Inode_Num;index++) //计算文件数目与目录数目
{
if(Inode[index].decide==0)
{
Dir_Num++;
}
if(Inode[index].decide==1)
{
File_Num++;
}
}
//打印信息
cout<<"The Used Block: "<<Used_Block_Size<<"byte "
<<double(Used_Block_Size)/1024<<"kb"<<endl;
cout<<"The Free Block: "<<Free_Block_Size<<"byte "
<<double(Free_Block_Size)/1024<<"kb"<<endl;
cout<<"The total number of dir is: "<<Dir_Num<<endl;
cout<<"The total number of file is: "<<File_Num<<endl;
}
/*******************************************************************************************
根据输入的节点号输出绝对路径
*******************************************************************************************/
char* Whole_Path(int index)
{
int parent;
char*whole=new char;
char*temp=new char;
if(index==0) //根目录的绝对路径
{
strcpy(whole,"L:");
return whole;
}
parent=index;
while(parent!=-1) //非根目录时的绝对路径
{
if(parent==index)
{
strcpy(whole,Inode[parent].name);
parent=Inode[parent].parent;
}
else
{
strcpy(temp,Inode[parent].name);
strcat(temp,"/");
strcat(temp,whole);
strcpy(whole,temp);
parent=Inode[parent].parent;
}
}
return whole;
}
/*******************************************************************************************
在父目录下搜索文件和目录,成功返回子节点索引号,失败返回-1
Name_Ptr为目录或文件名,parent确定父节点的索引值
*******************************************************************************************/
int search(char*Name_Ptr,int parent) //搜索该文件或目录是否已经存在
{
int i,temp;
struct inode*Parent_Ptr=&Inode[parent];
for(i=0;i<15;i++)
{
if(Inode_Bitmap[Parent_Ptr->child[i]]==1) //使用Bitmap来判断该子节点是否存在
{
temp=Parent_Ptr->child[i];
if(strcmp(Name_Ptr,Inode[temp].name)==0)
return temp;
}
}
return -1;
}
/*******************************************************************************************
在父目录下搜索文件和目录,成功返回在父目录下的标号,失败返回-1
Name_Ptr为目录或文件名,parent确定父节点的索引值
*******************************************************************************************/
int Search_Other(char*Name_Ptr,int parent) //搜索该文件或目录是否已经存在
{
int i,temp;
struct inode*Parent_Ptr=&Inode[parent];
for(i=0;i<15;i++)
{
if(Inode_Bitmap[Parent_Ptr->child[i]]==1)
{
temp=Parent_Ptr->child[i];
if(strcmp(Name_Ptr,Inode[temp].name)==0)
return i; //与search函数的惟一区别在于返回的是在父目录下的索引值
}
}
return -1;
}
/*******************************************************************************************
根据输入路径获得最后一个文件或目录名
*******************************************************************************************/
char* Get_Name(char*path)
{
char*temp=new char;
char*Curr_Path=new char;
int length=strlen(path);
int i=0;
int j=0;
temp=strchr(path,'/'); //strchr函数返回第一次出现字符的位置指针
if(!temp) //相对路径或根目录
{
return path;
}
else //完整路径
{ //找到最后一个文件名
while(*path!='\0') //j为最后一个'/'的位置
{
path++;
i++;
if(*path=='/')
j=i;
}
Curr_Path=path-length+j+1; //当前文件或目录名
return Curr_Path;
}
}
/*******************************************************************************************
根据输入路径获得父目录索引值,判断父目录是否存在
找到父目录返回其索引值,否则返回-2
重要功能函数,与search函数一起使用可判断文件或目录是否存在
*******************************************************************************************/
int Get_Parent(char*path)
{
int i,j,length,parent;
i=j=0;
length=strlen(path);
int Curr_Path_Num=0; //记录与name相同的文件或目录的数目
int Same_Path_Inode[15]; //记录与name相同的文件或目录的inode号
char*temp=new char;
char*Curr_Temp=new char;
char*Parent_Temp=new char;
char*Path_Parent=new char;
char*Parent_Name=new char;
temp=strchr(path,'/');
if(!strcmp(path,"L:")) //根目录情况
{
return -1; //path为根目录,其索引值为-1
}
else
{
if(!temp) //相对路径情况
{
return curr;
}
else //绝对路径情况
{
while(*path!='\0') //查找其父目录
{
path++;
i++;
if(*path=='/')
j=i;
}
strncpy(Path_Parent,path-length,j);
Path_Parent[j]='\0'; //Path_Parent为父目录名
Parent_Name=Get_Name(Path_Parent);
for(int k=0;k<15;k++) //初始化Same_Path_Inode[15]数组
{
Same_Path_Inode[k]=0;
}
for(int l=0;l<Inode_Num;l++)
{
if(!strcmp(Parent_Name,Inode[l].name))
//计算与name相同的文件名数目及inode号
{
Curr_Path_Num++;
Same_Path_Inode[Curr_Path_Num]=Inode[l].index;
}
}
for(int m=1;m<=Curr_Path_Num;m++)
{
parent=Same_Path_Inode[m];
do
{
if(parent==Same_Path_Inode[m])
{
strcpy(Curr_Temp,Inode[parent].name);
parent=Inode[parent].parent;
}
else
{
strcpy(Parent_Temp,Inode[parent].name);
strcat(Parent_Temp,"/");
strcat(Parent_Temp,Curr_Temp);
strcpy(Curr_Temp,Parent_Temp);
parent=Inode[parent].parent;
}
}
while(parent!=-1);
if(!strcmp(Curr_Temp,Path_Parent)&&Inode[Same_Path_Inode[m]].decide==0)
{
return Same_Path_Inode[m]; //找到父目录
}
}
return -2; //找不到父目录
}
}
}
/*******************************************************************************************
判断命名中是否含有某字符
作用在于限制在文件或目录名中出现':'和'/'
*******************************************************************************************/
int panduan(char *path,char s)
{
while(*path!='\0')
{
if(*path==s)
return 1; //出现字符s返回1
path++;
}
return 0; //未出现字符s返回0
}
/*******************************************************************************************
对目录进行初始化,返回inode索引节点
在md函数中被使用
*******************************************************************************************/
int Dir_Init(int parent,char *path)
{
if(panduan(path,'/')||panduan(path,':')) //判断命名中是否含'/'和':'
{
return -1;
}
for(int i=1;i<Inode_Num;i++)
{
if(Inode_Bitmap[i]==0) //有空闲Inode区
{
for(int j=0;j<15;j++)
{
if(Inode[parent].child[j]==-1) //父节点的子目录数未满
{
//初始化superblock及Inode_Bitmap
super.Free_Inode--;
Inode_Bitmap[i]=1;
//初始化占用的Inode节点
Inode[i].decide=0; //目录的标志
strcpy(Inode[i].name,path); //对目录命名
Inode[i].First_Block=-1; //目录不占用磁盘块
Inode[i].length=0;
Inode[i].index=i;
Inode[i].parent=parent;
Inode[i].Child_Num=0;
GetLocalTime(&Inode[i].ctime); //获得当前时间
//初始化目录的父节点
Inode[parent].Child_Num++; //子节点数+1
Inode[parent].child[j]=i; //初始化子节点索引
return i;
}
}
}
}
return -1;
}
/*******************************************************************************************
创建目录md主函数
创建成功返回父目录Inode索引号,创建失败返回-1或-2
*******************************************************************************************/
int md(char *path)
{
int parent;
parent=Get_Parent(path);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -