📄 os.cpp
字号:
}
/***************************************************************************************************************
在指定的目录下创建目录,如果成功则返回目录的索引号,否则返回-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 + -