📄 os.cpp
字号:
type为1时,写文件;
type为2时,写磁盘块
该函数只有在创建和删除时才调用
****************************************************************************************************************/
void write_bit(int pos,int type)
{
if(type==0)
{
fseek(fp,sizeof(int)*(pos+3),SEEK_SET);
fwrite(&dir_flag[pos],sizeof(int),1,fp);
}
else if(type==1)
{
fseek(fp,sizeof(int)*(DIR_NUM+pos+3),SEEK_SET);
fwrite(&file_flag[pos],sizeof(int),1,fp);
}
else
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+pos+3),SEEK_SET);
fwrite(&block_flag[pos],sizeof(int),1,fp);
}
}
/***************************************************************************************************************
//写回目录或文件节点的控制信息
//type为0时,写目录
//type为1时,写文件
//有目录或文件的控制信息被修改,该函数就被调用
****************************************************************************************************************/
void write_inode(int pos,int type)
{
if(type==0)
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*pos,SEEK_SET);
fwrite(&dir[pos],sizeof(struct dir_node),1,fp);
}
else
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*pos,SEEK_SET);
fwrite(&file[pos],sizeof(struct file_node),1,fp);
}
}
/***************************************************************************************************************
//显式保存文件的核心函数
****************************************************************************************************************/
void savefile(int file_id)
{
if(al_fflag[file_id]%2!=0) //如果创建或删除,需要写回磁盘
{
write_bit(file_id,1);
al_fflag[file_id]=0;
}
if(al_file[file_id]>0) //如果控制信息被修改,需要写回磁盘
{
write_inode(file_id,1);
al_file[file_id]=0;
for(int i=0;i<file[file_id].block_count;i++)
{
int temp=file[file_id].block[i];
if(al_bflag[temp]%2!=0) //如果磁盘块被释放或被占用,需要写回磁盘
{
write_bit(temp,2);
al_bflag[temp]=0;
}
}
}
}
void save_dir(int dir_id) //保存空目录函数
{
if(al_dflag[dir_id]%2!=0) //如果删除或创建,需要写回磁盘
{
write_bit(dir_id,0);
al_dflag[dir_id]=0;
}
if(al_dir[dir_id]>0) //如果控制信息被修改,需要写回磁盘
{
write_inode(dir_id,0);
al_dir[dir_id]=0;
}
}
void save(int dir_id) //保存一个目录及它下面的所有目录及文件
{ //用了递归
for(int i=0;i<dir[dir_id].dir_count;i++)
save(dir[dir_id].child_dir[i]);
for(i=0;i<dir[dir_id].file_count;i++)
savefile(dir[dir_id].child_file[i]);
save_dir(dir_id);
}
/***************************************************************************************************************
//格式化,相当于重新创建文件系统
****************************************************************************************************************/
void format()
{
create_file_system();
fp=fopen(file_system_name,"rb+");
if(fp==NULL)
{
printf("Open file system error!\n");
exit(1);
}
curr=0;
curr_dir=&dir[curr]; //设置当前目录为根目录
strcpy(curr_path,curr_dir->dir_name);
strcat(curr_path,"/");
}
/***************************************************************************************************************
//打开文件系统
****************************************************************************************************************/
void open_file_system()
{
int flag=0;
fp=fopen(file_system_name,"rb"); //以读方式打开,如果不存在,则创建文件系统
if(fp==NULL)
{
create_file_system();
flag=1;
}
fp=fopen(file_system_name,"rb+"); //以读写方式打开
if(fp==NULL)
{
printf("Open file system error!\n");
exit(1);
}
if(flag==0) //如果该文件系统早就创建,则将其信息读入主存
{
fseek(fp,0,SEEK_SET); //读超级块信息
fread(&used_dir,sizeof(int),1,fp);
fread(&used_file,sizeof(int),1,fp);
fread(&used_block,sizeof(int),1,fp);
for(int i=0;i<DIR_NUM;i++)
fread(&dir_flag[i],sizeof(int),1,fp);
for(i=0;i<FILE_NUM;i++)
fread(&file_flag[i],sizeof(int),1,fp);
for(i=0;i<BLOCK_NUM;i++)
fread(&block_flag[i],sizeof(int),1,fp);
for(i=0;i<DIR_NUM;i++) //读目录及文件的控制信息
if(dir_flag[i]==1)
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*i,SEEK_SET);
fread(&dir[i],sizeof(struct dir_node),1,fp);
}
for(i=0;i<FILE_NUM;i++)
if(file_flag[i]==1)
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*i,SEEK_SET);
fread(&file[i],sizeof(struct file_node),1,fp);
}
}
fflush(fp);
curr=0;
curr_dir=&dir[curr]; //设置当前目录为根目录
strcpy(curr_path,curr_dir->dir_name);
strcat(curr_path,"/");
}
/***************************************************************************************************************
//关闭文件系统,并保存相应信息,这是系统隐式保存文件及目录的方法
****************************************************************************************************************/
void close_file_system()
{
save(0);
for(int i=0;i<DIR_NUM;i++)
if(al_dflag[i]%2!=0)
write_bit(i,0);
for(i=0;i<FILE_NUM;i++)
if(al_fflag[i]%2!=0)
write_bit(i,1);
for(i=0;i<BLOCK_NUM;i++)
if(al_bflag[i]%2!=0)
write_bit(i,2);
fseek(fp,0,SEEK_SET);
fwrite(&used_dir,sizeof(int),1,fp);
fwrite(&used_file,sizeof(int),1,fp);
fwrite(&used_block,sizeof(int),1,fp);
fclose(fp);
}
/***************************************************************************************************************
打印命令及解释
****************************************************************************************************************/
void help()
{
printf("Commands: Explanation:\n");
printf(" 0 exit: Exit!\n");
printf(" 1 format: Format the disk!\n");
printf(" 2 mkf: Create a new file!\n");
printf(" 3 mkd: Create a new directory!\n");
printf(" 4 delf: Delete a file!\n");
printf(" 5 deld: Delete a directory!\n");
printf(" 6 cd: Change the current directory!\n");
printf(" 7 dir: Show the current files and directories!\n");
printf(" 8 tree: Show directory tree!\n");
printf(" 9 help: Print commands!\n");
}
/***************************************************************************************************************
命令接受及解析,转入相应函数运行
****************************************************************************************************************/
void run()
{
char *command[10]={"exit","dir","mkf","mkd","delf","deld","cd","format","help","tree"};
char buf1[256]; /* 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 */
char buf2[2048];
char buf3[128];
char buf4[128];
int key,num,index,del_pos,parent,p;
char *s,flag='\0';
cout<<"=============================================================================="<<endl;
help();
cout<<"=============================================================================="<<endl;
cout<<"Input help to print commands!"<<endl;
while(1)
{
strcpy(buf1,"");
strcpy(buf2,"");
strcpy(buf3,"");
strcpy(buf4,"");
p=0;
printf("\n%s\n",curr_path);
cin.getline(buf1,256,'\n');
key=-1;
for(int i=0;i<=10;i++) //命令匹配
if(strncmp(buf1,command[i],(int)strlen(command[i]))==0)
{
key=i;
break;
}
if(key!=-1) //参数分解
{
s=strchr(buf1,' ');
if(s!=NULL)
{
index=(int)(s-buf1);
while(buf1[index]==' ')
index++;
strcpy(buf3,buf1+index);
s=strchr(buf3,' ');
if(s!=NULL)
{
num=(int)(s-buf3);
buf3[num]='\0';
}
s=strrchr(buf1+index,' ');
if(s!=NULL)
{
index=(int)(s-buf1);
strcpy(buf4,buf1+index+1);
}
}
}
switch(key)
{
case -1:
printf("The command you input not exist!\n");
break;
case 0: //exit
return;
case 1: //dir
list();
break;
case 2: //mkf
if((int)strlen(buf3)==0)
{
printf("please input the name of the file:\n");
cin.getline(buf3,128,'\n');
}
if(create(buf3)!=-1)
printf("Succeed!");
break;
case 3: //mkd
if((int)strlen(buf3)==0)
{
printf("please input the name of the directory:\n");
cin.getline(buf3,128,'\n');
}
if(md(buf3)!=-1)
printf("Succeed!");
break;
case 4: //delf
if((int)strlen(buf3)==0)
{
printf("please input the name of the file:\n");
cin.getline(buf3,128,'\n');
}
if(delfile(buf3)!=-1)
printf("Succeed!");
break;
case 5: //deld
if((int)strlen(buf3)==0)
{
printf("please input the name of the directory:\n");
cin.getline(buf3,128,'\n');
}
parent=get_parent(buf3,p);
if(parent==-1)
{
printf("Path name error!");
break;
}
if((del_pos=search(parent,buf3+p,0,index))==-1)
{
printf("The directory to delete not exist in current directory!\n");
break;
}
if(dir[del_pos].dir_count>0 || dir[del_pos].file_count>0)
{
printf("The directory is not empty!\nAre you sure to delete it?('Y' or 'N')");
cin.getline(&flag,32,'\n');
if(flag!='Y' && flag!='y')
break;
}
del_dir(parent,del_pos,index);
printf("Succeed!");
break;
case 6: //cd
if((int)strlen(buf3)==0)
{
printf("please input the name of the diectory:\n");
cin.getline(buf3,128,'\n');
}
if(change_dir(buf3)!=-1)
printf("Succeed!");
break;
case 7:
format();
printf("Succeed!");
break;
case 8:
help();
break;
case 9:
show_tree();
break;
}
}
}
void main()
{
open_file_system();
run();
close_file_system();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -