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

📄 os.cpp

📁 操作系统课程设计 1、模拟UNIX(linux)文件系统 [问题描述] 在任一OS下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

/***************************************************************************************************************

    在指定的目录下创建目录,如果成功则返回目录的索引号,否则返回-1 
	如果父目录已满,则创建失败

****************************************************************************************************************/
int create_dir(int parent,char *dir_name)                
{                                                  
	if(dir[parent].dir_count==DIR_NUM-1)     //如果父目录已满,则创建失败               
	{
		cout<<"Parent directory is full!"<<endl;
		return -1;
	}
	int pos=get_dir(parent,dir_name);              //开始创建目录
	if(pos==-1)
	{
		cout<<"Create directory error!"<<endl;
		return -1;
	}

	struct dir_node *p=&dir[parent];               //修改父目录的控制信息
	int top=p->dir_count;         
	p->child_dir[top]=pos;
	p->dir_count++;
	al_dir[parent]++;

	return pos;
}

/***************************************************************************************************************

    创建目录的主调函数,它的参数只有用户输入
	如果创建成功,则返回目录的索引号,否则返回-1

****************************************************************************************************************/
int md(char *name)                                
{                                                  
	int parent,p=0;                                
	parent=get_parent(name,p);
	if(parent==-1)                                 //父目录找不到,输入有误,创建失败
	{
		cout<<"Path name error!"<<endl;
		return -1;
	}
	return create_dir(parent,name+p);              //开始创建目录
}
/***************************************************************************************************************
    创建文件的主调函数,直接接受用户输入成功返回文件的索引号,否则返回-1
****************************************************************************************************************/
int create(char *name)                             
{                                               
	int parent,p=0;
	parent=get_parent(name,p);
	if(parent==-1)                                 //找不到父目录,输入错误,创建失败
	{
		cout<<"Path name error!"<<endl;
		return -1;
	}
	return create_file(parent,name+p);             //开始创建文件
}
/***************************************************************************************************************
    删除文件,调用该函数的前提是已经取得要删除文件的索引号
****************************************************************************************************************/
void del_file(int pos)                                              
{                                                  
	return_block(pos);                             //释放磁盘块
	file_flag[pos]=0; 
	used_file--;
	al_fflag[pos]++;
	al_file[pos]=0;

	if(open_files[pos]>0)                          //如果已经获得缓冲区,则立即释放
	{
		int buf_id=get_buffer_id(pos);
		buffer[buf_id].flag=0;
		open_files[pos]=0;
	}
}

/***************************************************************************************************************
在指定的目录下删除文件,删除成功则返回文件的索引号,否则返回-1   
****************************************************************************************************************/
int del_file(int parent,char *file_name)                       
{                                                  
	int del_pos,index;
	if((del_pos=search(parent,file_name,1,index))==-1)//搜索该文件是否存在,不存在则删除失败
	{
		printf("The file to delete not exist!\n");
		return -1;
	}
	del_file(del_pos);                             //开始删除文件

	struct dir_node *p=&dir[parent];               //修改父目录的控制信息
	if(p->file_count>=2)
	{
		int top=p->file_count-1;         	
		p->child_file[index]=p->child_file[top];
	}
	p->file_count--;
	al_dir[parent]++;

	return del_pos;
}

/***************************************************************************************************************
                      删除文件的主调函数   
****************************************************************************************************************/
int delfile(char *name)                           
{
	int parent,p=0;
	parent=get_parent(name,p);
	if(parent==-1)
	{
		printf("Path name error!\n");
		return -1;
	}
	return del_file(parent,name+p);
}

/***************************************************************************************************************
    删除指定的目录节点,该目录已经为空
****************************************************************************************************************/
void del_dir(int pos)                                                
{
	dir_flag[pos]=0;  
	used_dir--;
	al_dflag[pos]++;
	al_dir[pos]=0;
}

/***************************************************************************************************************
删除一个指定目录及它下面的所有文件及所有目录   
****************************************************************************************************************/
void del(int pos)                                                           
{
	for(int i=0;i<dir[pos].file_count;i++)         //删除当前目录下的所有文件
		del_file(dir[pos].child_file[i]);
	for(i=0;i<dir[pos].dir_count;i++)              //删除子目录
		del(dir[pos].child_dir[i]);
	del_dir(pos);                                  //删除当前目录
}

/***************************************************************************************************************
在一个指定的目录下删除一个目录及它下面的所有文件及所有目录      
****************************************************************************************************************/
void del_dir(int parent,int del_pos,int index)                    
{                                                  
	del(del_pos);                                  //开始删除目录
	if(dir[parent].dir_count>=2)                   //修改父目录的控制信息
	{
		int top=dir[parent].dir_count-1;
		dir[parent].child_dir[index]=dir[parent].child_dir[top];
	}
	dir[parent].dir_count--;
	al_dir[parent]++;
}

/***************************************************************************************************************
    用于设置当前路径
****************************************************************************************************************/
void paste(int dir_id)                           
{
	if(dir_id==0)
		return;
	paste(dir[dir_id].parent);
	strcat(curr_path,dir[dir_id].dir_name);
	strcat(curr_path,"/");
}

/***************************************************************************************************************
    改变工作目录,成功则返回该目录的索引号,否则返回-1
****************************************************************************************************************/
int change_dir(char *name)                         
{                                                  
	int parent,p=0,pos,index;
	if(strcmp(name,"/")==0)
		pos=0;
	else if(strcmp(name,"..")==0)
		pos=curr_dir->parent;
	else
	{	
		parent=get_parent(name,p);	
		if(parent==-1)	
		{		
			printf("Path name error!\n");		
			return -1;	
		}
		pos=search(parent,name+p,0,index);
	}
	if(pos==-1)                                    //如果该目录不存在,则失败
	{
		printf("The dictory not exist!\n");
		return -1;
	}
	curr_path[3]='\0';
	paste(pos);
	curr=pos;                                      //改变当前目录及路径
	curr_dir=&dir[curr];                                                 
	return curr;                               
}

/***************************************************************************************************************
    该函数用于打印|用,可以将目录结构以树形显示
****************************************************************************************************************/
int count[DIR_NUM];                                //用于显示目录树时用

void print_sp(int dir_id)                         
{                                                  
	if(dir_id<0)
		return;
	print_sp(dir[dir_id].parent);
	if(dir[dir_id].dir_count>count[dir_id])
		printf("|");
	else
		printf(" ");
	for(int i=0;i<6;i++)
		printf(" ");
}

/***************************************************************************************************************
    该函数在每打印一个目录或文件名之前调用
****************************************************************************************************************/
void print_pre(int id,int type)                    
{
	int parent,pre;
	if(type==0)
		parent=dir[id].parent;
	else
		parent=file[id].parent;
	pre=dir[parent].parent;
	print_sp(pre);
}

/***************************************************************************************************************
    打印文件名
****************************************************************************************************************/
void print_file(int file_id)                       
{
	print_pre(file_id,1);
	printf("|");
	for(int i=0;i<6;i++)
		printf("_");
	printf("%s\n",file[file_id].file_name);
}

/***************************************************************************************************************
    打印目录名
****************************************************************************************************************/
void print_dir(int dir_id)                         
{
	print_pre(dir_id,0);
	printf("|");
	for(int i=0;i<6;i++)
		printf("_");
	printf("%s\057\n",dir[dir_id].dir_name);
	count[dir[dir_id].parent]++;
}

/***************************************************************************************************************
    打印树形结构的核心函数
****************************************************************************************************************/
void print(int dir_id)                             
{
	print_dir(dir_id);
	for(int i=0;i<dir[dir_id].file_count;i++)
		print_file(dir[dir_id].child_file[i]);
	for(i=0;i<dir[dir_id].dir_count;i++)
		print(dir[dir_id].child_dir[i]);
}

/***************************************************************************************************************
     打印树形结构的主调函数
****************************************************************************************************************/
void show_tree()                                  
{
	if(used_file==0 && used_dir==1)
	{
		printf("The file system is empty!\n");
		return;
	}
	printf("%s\057\n",dir[0].dir_name);
	for(int i=0;i<DIR_NUM;i++)
		count[i]=0;
	for(i=0;i<dir[0].file_count;i++)
		print_file(dir[0].child_file[i]);
	for(i=0;i<dir[0].dir_count;i++)
		print(dir[0].child_dir[i]);
}

/***************************************************************************************************************
    以下几个函数用于显示当前目录下面的目录和文件,跟上面不同的是,它不能显示目录及文件之间的关系,
	但它可以显示一些细节,如创建时间,文件长度

  显示当前目录下的文件和子目录信息
****************************************************************************************************************/
void show_dir(int dir_id)                         
{                                                  
	printf("%s",dir[dir_id].dir_name);             
	for(int i=strlen(dir[dir_id].dir_name);i<20;i++)
		printf(" ");
	printf("<DIR>");
	for(i=25;i<30;i++)
		printf(" ");
	printf("%d-%.2d-%.2d %.2d:%.2d:%.2d\n",dir[dir_id].ctime.wYear,dir[dir_id].ctime.wMonth,dir[dir_id].ctime.wDay,dir[dir_id].ctime.wHour,dir[dir_id].ctime.wMinute,dir[dir_id].ctime.wSecond);
}

/***************************************************************************************************************
    显示一个文件
****************************************************************************************************************/
void show_file(int file_id)                        
{
	printf("%s",file[file_id].file_name);
	for(int i=strlen(file[file_id].file_name);i<20;i++)
		printf(" ");
	printf("<FILE>");
	for(i=26;i<30;i++)
		printf(" ");
	printf("%d-%.2d-%.2d %.2d:%.2d:%.2d",file[file_id].ctime.wYear,file[file_id].ctime.wMonth,file[file_id].ctime.wDay,file[file_id].ctime.wHour,file[file_id].ctime.wMinute,file[file_id].ctime.wSecond);
	for(i=0;i<8;i++)
		printf(" ");
	int length=file[file_id].file_length;
	if(open_files[file_id]==2)                     //如果该文件已经以写的方式被打开,则需改变
	{
		int buf_id=get_buffer_id(file_id);
		length=buffer[buf_id].length;
	}
	printf("len: %d bytes\n",length);
}

/***************************************************************************************************************
      显示目录及文件的核心函数,用了递归思想
****************************************************************************************************************/
void show(int dir_id)                                                     
{
	for(int i=0;i<dir[dir_id].file_count;i++)
		show_file(dir[dir_id].child_file[i]);
	for(i=0;i<dir[dir_id].dir_count;i++)
		show_dir(dir[dir_id].child_dir[i]);
}

/***************************************************************************************************************
    显示文件及目录的主调函数
****************************************************************************************************************/
void list()                                      
{ 
	show(curr);                                    //该函数的参数表示根目录的索引
	printf("%d files.",curr_dir->file_count);  //统计文件数
	printf("\n%d dirs.",curr_dir->dir_count);    //统计目录数
}

/***************************************************************************************************************
写回目录节点、文件节点或磁盘块的占用标志
type为0时,写目录;

⌨️ 快捷键说明

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