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

📄 os.cpp

📁 操作系统课程设计 1、模拟UNIX(linux)文件系统 [问题描述] 在任一OS下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include<stdio.h>                          
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<iostream.h>
#include<windows.h>
#include "define.h"

/***************************************************************************************************************
         创建文件系统
****************************************************************************************************************/
void create_file_system()                                     
{
	fp=fopen(file_system_name,"wb+");              //以读写方式打开,如果存在,则覆盖原来信息,
	if(fp==NULL)                                   //否则创建该文件    
	{
		cout<<"Create file system error!\n"<<endl;
		exit(1);
	}
                                                   //申请空间
	int total=sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+BLOCK_SIZE*BLOCK_NUM;
	for(long len=0;len<total;len++)
		fputc(0,fp);

	fseek(fp,0,SEEK_SET);                          //写超级块信息
	used_dir=1;
	fwrite(&used_dir,sizeof(int),1,fp);	
	used_file=0;
	used_block=0;
	fwrite(&used_file,sizeof(int),2,fp);
	dir_flag[0]=1;
	fwrite(&dir_flag[0],sizeof(int),1,fp);         //标志对应目录节点、文件节点的使用情况
	fwrite(&dir_flag[1],sizeof(int),DIR_NUM+FILE_NUM+BLOCK_NUM-1,fp);

	strcpy(dir[0].dir_name,"A:");                  //写根目录信息
	dir[0].dir_count=0;
	dir[0].file_count=0;
	dir[0].parent=-1;
	GetLocalTime(&dir[0].ctime);                   //获得当前时间
	fwrite(&dir[0],sizeof(struct dir_node),1,fp);
                                                   
	for(int i=0;i<DIR_NUM;i++)                     //将所有标记清零
	{
		al_dir[i]=0;
		al_dflag[i]=0;
		dir[i].dir_count=0;
		dir[i].file_count=0;
	}
	for(i=0;i<FILE_NUM;i++)                
	{
		al_file[i]=0;
		al_fflag[i]=0;
		open_files[i]=0;
	}
	for(i=0;i<BLOCK_NUM;i++)                
		al_bflag[i]=0;

	for(i=0;i<BUF_NUM;i++)
		buffer[i].flag=0;

	fflush(fp);
	fclose(fp);
}
/***************************************************************************************************************
			搜索目录或文件,成功则返回该文件或目录的索引失败则返回-1,
			type用来区分要搜索的是文件还是目录0表示目录,1表示文件,
			index用来指定找到的文件或目录在父目录下的位置
****************************************************************************************************************/
int search(int parent,char *name,int type,int &index) 
{                                                      
	struct dir_node *p=&dir[parent];               
	int i,temp;                                    
	if(type==0)    //表示目录                                                
		for(i=0;i<p->dir_count;i++)
		{
			temp=p->child_dir[i];
			if(strcmp(name,dir[temp].dir_name)==0)// 字符串相等时 
			{
				index=i;
				return temp;
			}
		}
	else
		for(i=0;i<p->file_count;i++)//表示找文件 
		{
			temp=p->child_file[i];
			if(strcmp(name,file[temp].file_name)==0)
			{
				index=i;
				return temp;
			}
		}

	return -1;
}
/***************************************************************************************************************

根据输入的字符串,获得父目录及真正的文件或目录名,引用参数p用来指定目录或文件名的起始位置

****************************************************************************************************************/
int get_parent(char *name,int &p)         
{                                          
	char buf[32],*path,*s;                         
	int pos,start=0,index;
	path=new char[128];
	strcpy(path,name);

	s=strrchr(path,'/');                   //如果没有指定路径,则将当前目录指定为父目录
	if(s==NULL)                              
		return curr;

	pos=(int)(s-path);
	p=pos+1;
	if(p==(int)strlen(path))
		return -1;
	path[p]='\0';
	
	s=strchr(path,'/');
	pos=(int)(s-path);
	if(strncmp(path,"A:",pos)!=0)                  //前面没有跟根目录名,则从当前目录往下搜索
		start=curr;
	else	
		path+=3;
	while(start!=-1 && (int)strlen(path)>0)        //进行搜索,知道路径名结束或出现不匹配
	{
		s=strchr(path,'/');
		pos=(int)(s-path);
		strncpy(buf,path,pos);
		buf[pos]='\0';
		start=search(start,buf,0,index);
		path+=pos+1;
	}
	return start;                                 
}                                                  
/***************************************************************************************************************

为文件申请磁盘块,一次调用申请一块,成功则返回磁盘块索引,失败返回-1 
****************************************************************************************************************/
int get_block(int pos)                                                
{                                                  
	for(int i=0;i<BLOCK_NUM;i++)
		if(block_flag[i]==0)
		{                                          //修改磁盘块使用情况及文件的控制信息
			block_flag[i]=1;
			al_bflag[i]++;               //目录节点占用标志
			used_block++;                //已用的磁盘块数
			int top=file[pos].block_count;
			file[pos].block[top]=i;
			file[pos].block_count++;
			return i;
		}
	return -1;
}
/***************************************************************************************************************

  释放文件占用的磁盘块,用于删除文件时用
****************************************************************************************************************/
void return_block(int pos)                        
{
	for(int i=0;i<file[pos].block_count;i++)
	{
		int temp=file[pos].block[i];
		block_flag[temp]=0;
		al_bflag[temp]++;
	}
	used_block-=file[pos].block_count;
}

int get_dir(int parent,char *dir_name)             //创建目录节点,成功则返回目录的索引,失败则返回-1
{
	int index;
	if(search(parent,dir_name,0,index)!=-1)        //搜索在父目录下是否有同名目录,有则创建失败        
	{
		cout<<"Directory name repeated!"<<endl;
		return -1;
	}
	for(int i=1;i<DIR_NUM;i++)                     //搜索空闲的目录节点           
		if(dir_flag[i]==0)
		{                                          //登记并给目录节点初始化
			dir_flag[i]=1; 
			al_dflag[i]++;
			al_dir[i]++;
			used_dir++;
			strcpy(dir[i].dir_name,dir_name);
			dir[i].dir_count=0;
			dir[i].file_count=0;
			dir[i].parent=parent;
			GetLocalTime(&dir[i].ctime);           //获得当前时间
			return i;
		}
	return -1;
}
/***************************************************************************************************************

       创建文件节点,成功则返回文件的索引号,失败返回-1
****************************************************************************************************************/
int get_file(int parent,char *file_name)          
{
	int index;
	if(search(parent,file_name,1,index)!=-1)       //搜索在父目录下是否有同名文件存在,有则创建失败
	{
		cout<<"File name repeated!"<<endl;
		return -1;
	}
	for(int i=0;i<FILE_NUM;i++)                    //搜索空闲的文件节点             
		if(file_flag[i]==0)
		{
			strcpy(file[i].file_name,file_name);
			file[i].block_count=0;
			if(get_block(i)==-1)                   //给新创建的文件申请磁盘块,如果失败,创建文件           
			{                                      //将失败
				cout<<"Disk volumn error!"<<endl;
				return -1;
			}
			file_flag[i]=1;
			al_fflag[i]++;                         //登记并给文件节点初始化
			al_file[i]++;
			used_file++;
			file[i].file_length=0;
			file[i].parent=parent;
			GetLocalTime(&file[i].ctime);          //获得当前时间
			return i; 
		}
	return -1;
}
/***************************************************************************************************************

       给文件申请缓冲区,打开文件时调用,失败时返回-1

****************************************************************************************************************/
int get_buffer(int pos)
{                            
	for(int i=0;i<BUF_NUM;i++)
		if(buffer[i].flag==0)                      //buffer[] 缓冲区数组    
		{
			buffer[i].flag=1;                      //修改使用标志并初始化
			buffer[i].file_id=pos;
			buffer[i].length=0;
			buffer[i].offset=0;
			return i;
		}
	return -1;
}
/***************************************************************************************************************

       得到被打开文件的缓冲区索引号,失败则返回-1

****************************************************************************************************************/
int get_buffer_id(int pos)                        
{
	for(int i=0;i<BUF_NUM;i++)
		if(buffer[i].flag==1 && buffer[i].file_id==pos)
			return i;
	return -1;
}
/***************************************************************************************************************

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

****************************************************************************************************************/
int create_file(int parent,char *file_name)         
{                                                  
	if(dir[parent].file_count==16)                 
	{
		cout<<"Parent directory is full!"<<endl;
		return -1;
	}					
	int pos=get_file(parent,file_name);            //开始创建文件
	if(pos==-1)
	{
		cout<<"Create file error!"<<endl;
		return -1;
	}
                                           
	struct dir_node *p=&dir[parent];               //修改父目录的控制信息
	int top=p->file_count;              
	p->child_file[top]=pos;
	p->file_count++;
	al_dir[parent]++;

	return pos;
}

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

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

****************************************************************************************************************/
int create_dir(int parent,char *dir_name)                
{                                                  
	if(dir[parent].dir_count==8)                   
	{
		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);              //开始创建目录
}
/***************************************************************************************************************

⌨️ 快捷键说明

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