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

📄 main.cpp

📁 模拟unix文件系统的功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#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 + -