📄 模拟unix文件系统.c
字号:
}
else if( j==10 )
{
printf("文件已经写满!\n") ;
return ;
}
}
if( j==10 )
{
printf("文件已经写满!\n") ;
return ;
}
buffer[i-1]='\n' ;
buffer[i]='\0' ;
strcpy( fileBlock[address[j]].p, buffer) ;
printf("输入完毕!\n") ;
i_node[i_number].file_length+=strlen(buffer);
for( j=i+1;j<10;j++ )
{
strcpy(fileBlock[address[j]].p,"\0") ;
}
return ;
}
else
{
printf("权限不对,对不起!\n") ;
return ;
}
}
for(i=0;i<512;i++)
{
if(strcmp(filename,root[i].file_name)==0)
{
i_number=i;
InsertAFileIntoSystemFileTable( filename, i_number ) ;
break ;
}
}
if(i==512)
{
printf("对不起,找不到相应的文件\n");
return;
}
if( (currentuser!=i_node[i_number].file_userid) && (G_Write==(G_Write&i_node[i_number].file_mode))||
currentuser==i_node[i_number].file_userid )
{
for( i=0; i<10; i++ )
address[i]=i_node[i_number].file_address[i] ;
printf("请输入内容:文件以D结束\n") ;
i=0 ;
j=0 ;
flushall();
while( (buffer[i++]=getchar())!='D' )
{
if( i==512 && j<10 )
{
buffer[i]='\0' ;
strcpy( fileBlock[address[j]].p, buffer) ;
i=0 ;
j++ ;
i_node[i_number].file_length+=512 ;
}
else if( j==10 )
{
printf("文件已经写满!\n") ;
return ;
}
}
if( j==10 )
{
printf("文件已经写满!\n") ;
return ;
}
buffer[i-1]='\n' ;
buffer[i]='\0' ;
strcpy( fileBlock[address[j]].p, buffer) ;
printf("输入完毕!\n") ;
i_node[i_number].file_length+=strlen(buffer);
for( j=i+1;j<10;j++ )
{
strcpy(fileBlock[address[j]].p,"\0") ;
}
return ;
}
printf("对不起,你对该文件无写权限!\n") ;
}
void read_file(FILE *fp) // 读出系统文件的信息
{
int i;
fp=fopen("system","rb");
for(i=0;i<512;i++)
{
fread(&memory[i],sizeof(struct block),1,fp);
}
fread(&super_block,sizeof(struct block_super),1,fp);
for(i=0;i<512;i++)
{
fread(&i_node[i],sizeof(struct node),1,fp);
}
for(i=0;i<512;i++)
{
fread(&root[i],sizeof(struct dir),1,fp);
}
fclose(fp);
}
void readfile( char *filename)
{
int i_number ;
int i;
int address[10] ;
int active_node_location ;
i_number=findAFileInFileTable( filename , &active_node_location) ;
if( i_number!=-1 )
{
if( isAOperationElgal(i_number, 'R' )==1 )
{
for( i=0 ; i<10; i++ )
address[i]=i_node[i_number].file_address[i] ;
for( i=0; i<10; i++ )
{
printf("%s", fileBlock[address[i]].p);
}
return ;
}
else
{
printf("权限不对,对不起!\n") ;
return ;
}
}
for(i=0;i<512;i++)
{
if(strcmp(filename,root[i].file_name)==0)
{
i_number=i;
}
}
for( i=0; i<10; i++ )
address[i]=i_node[i_number].file_address[i] ;
if( (currentuser!=i_node[i_number].file_userid) && (G_Read==(G_Read&i_node[i_number].file_mode))||
currentuser==i_node[i_number].file_userid )
{
for( i=0; i<10; i++ )
{
printf("%s", fileBlock[address[i]].p);
}
return ;
}
printf("对不起,你无法读文件!\n") ;
}
void callback(int length) /* 回收磁盘空间 */
{
int i,j,k,m,q=0;
for(i=length-1;i>=0;i--)
{
k=address_buffer[i]; /* 需要提供要回收的文件的地址 */
m=49-super_block.n; /* 回收到栈中的哪个位置 */
if(super_block.n==50) /* 注意 当super_block.n==50时 m=-1;的值 */
{ /* super_block.n==50的时候栈满了,要将这个栈中的所有地址信息写进下一个地址中 */
for(j=0;j<50;j++)
{
memory[k].free[j]=super_block.free[j];
}
super_block.n=0;
memory[k].n=50;
}
memory[k].a=0;
if(m==-1)
{
m=49; /* 将下一个文件地址中的盘块号回收到栈底中,这个地址中存放着刚才满栈的地址的信息 */
}
super_block.free[m]=address_buffer[i]; /* 将下一个文件地址中的盘块号回收到栈中 */
super_block.n++;
}
}
void allot(int length) /* 分配空间 */
{
int i,j,k,m,p;
for(i=0;i<length;i++)
{
k=50-super_block.n; /* 超级块中表示空闲块的指针 */
m=super_block.free[k]; /* 栈中的相应盘块的地址 */
p=super_block.free[49]; /* 栈中的最后一个盘块指向的地址 */
if(m==-1||memory[p].a==1) /* 检测是否还有下一组盘块 */
{
printf("内存不足,不能够分配空间\n");
callback(length);
break;
}
if(super_block.n==1)
{
memory[m].a=1; /* 将最后一个盘块分配掉 */
address_buffer[i]=m;
super_block.n=0;
for(j=0;j<memory[m].n;j++) /* 从最后一个盘块中取出下一组盘块号写入栈中 */
{
super_block.free[j]=memory[m].free[j];
super_block.n++;
}
continue; /* 要跳过这次循环,下面的语句在IF中已经执行过 */
}
address_buffer[i]=m; /* 栈中的相应盘块的地址写进 文件地址缓冲区 */
memory[m].a=1;
super_block.n--;
}
}
void create_file(char filename[],int length) /* 创建文件 */
{
int i,j;
for(i=0;i<512;i++)
{
if(strcmp(filename,root[i].file_name)==0)
{
printf("文件已经存在,不允许建立重名的文件\n");
return;
}
}
for(i=0;i<512;i++)
{
if(root[i].i_num==-1)
{
root[i].i_num=i;
strcpy(root[i].file_name,filename);
strcpy(root[i].dir_name,cur_dir); /* 把当前目录名 给新建立的文件 */
i_node[i].file_style=style;
i_node[i].file_length=length;
i_node[i].file_userid=currentuser;
i_node[i].file_groupid=( currentuser==User1)?User2:User1 ;
//初始文件的权限对文件主都有,对同组用户只有读的权限
i_node[i].file_mode=O_Read|O_Write|O_Delete|O_Execute|G_Read;
InsertAFileIntoSystemFileTable(filename, root[i].i_num) ;
allot(length);
for(j=0;j<length;j++)
{
i_node[i].file_address[j]=address_buffer[j];
}
break;
}
}
}
void create_dir(char filename[]) /* 创建目录 */
{
style=0; /* 0代表文件类型是目录文件 */
create_file(filename,4);
style=1; // 用完恢复初值
}
void del_file(char filename[]) /* 删除文件 */
{
int i,j;
int i_number ;
for(i=0;i<512;i++)
{
if(strcmp(filename,root[i].file_name)==0)
{
i_number=i;
break ;
}
}
if(i==512)
{
printf("对不起,找不到相应的文件\n");
return;
}
if( ((currentuser!=i_node[i_number].file_userid) && (G_Delete==G_Delete&i_node[i_number].file_mode))||
currentuser==i_node[i_number].file_userid )
{
strcpy(root[i].file_name,"") ;
strcpy(root[i].dir_name,"") ;
for(j=0;j<10;j++) /* 删除文件后要将文件属性和目录项的各个值恢复初值 */
{
i_node[i_number].file_address[j]=-1; /* 地址恢复初值 */
}
root[i_number].i_num=-1 ;
return ;
}
else
{
printf("对比起,你无权删除此文件\n");
return ;
}
}
void del_dir(char filename[]) /* 删除目录 需要判断目录下时候为空,不为空就不删除 */
{
int i,j,k;
for(i=0;i<512;i++) /* 还要加条件判断要删除的目录是不是当前目录 */
{
k=root[i].i_num; /* 找到目录名字 */
if( strcmp(root[i].file_name,filename)==0 && strcmp(cur_dir,filename)!=0 && (i_node[k].file_style)==0 )
{
for(j=0;j<512;j++)
{
if(strcmp(filename,root[j].dir_name)==0)
{
del_file(root[j].file_name) ;
}
}
del_file(filename);
break;
}
else if( strcmp(root[i].file_name,filename)==0 && strcmp(cur_dir,filename)==0 && (i_node[k].file_style)==0 )
{
printf("对不起,你在当前目录下无法删除该目录,退回到父目录后在执行删除操作!\n") ;
break;
}
}
if(i==512)
{
printf("这个不是目录文件 或者不存在这个目录,或者你要删除的是当前目录\n");
}
}
void display_curdir() /* 显示当前目录下的文件列表 */
{
int i,k;
printf("\t\t文件名字 文件类型 文件长度 所属目录\n");
for(i=0;i<512;i++)
{
if(strcmp(cur_dir,root[i].dir_name)==0) /* 查询文件中 所在目录信息和当前目录信息相同的数据 */
{
k=root[i].i_num;
printf("\t\t %s\t",root[i].file_name); /* 文件名 */
printf("\t%d\t",i_node[k].file_style); /* 文件的类型 */
printf("%d\t",i_node[k].file_length); /* 文件的长度 */
printf("%s\n",root[i].dir_name); /* 文件所在的目录 */
}
}
}
void display_dir(char filename[]) /* 进入指定的目录 */
{
int i,k;
for(i=0;i<512;i++)
{
k=root[i].i_num; /* 判断文件类型是不是目录类型 */
if((strcmp(filename,root[i].file_name)==0) && (i_node[k].file_style==0))
{
strcpy(cur_dir,filename); /* 将要进入的指定目录设置为当前目录 赋值不要反了strcpy(目的,源) */
break;
}
}
if(i==512)
{
printf("没有这个目录\n");
}
}
void open_file(char filename[]) /* 打开文件 */
{
int i,j,k;
printf("\t\t文件名字 文件类型 文件长度 所属目录\n");
for(i=0;i<512;i++)
{
k=root[i].i_num;
if(strcmp(filename,root[i].file_name)==0 && (i_node[k].file_style==1))
{
printf("\t\t %s\t",root[i].file_name); /* 文件名 */
printf("\t%d\t",i_node[k].file_style); /* 文件的类型 */
printf("%d\t",i_node[k].file_length); /* 文件的长度 */
printf("%s\n",root[i].dir_name); /* 文件所在的目录 */
printf("\n");
InsertAFileIntoSystemFileTable(filename, k) ;
break;
}
}
if(i==512)
{
printf("没有这个文件 或者这个文件不是正规文件\n");
}
}
void back_dir() /* 返回上一级目录 */
{
int i,k;
for(i=0;i<512;i++) /* 查询和当前目录名相同的目录文件名 */
{
k=root[i].i_num;
if(strcmp(cur_dir,root[i].file_name)==0 && (i_node[k].file_style==0))
{
strcpy(cur_dir,root[i].dir_name); /* 将查询到的目录文件名 所在的目录赋值给当前目录 */
}
}
}
void display_sys() /* 显示系统信息(磁盘使用情况) */
{
int i,m,k=0;
for(i=0;i<512;i++)
{
if(memory[i].a==0)
k++;
}
m=512-k;
printf("空闲的盘块数是:\t");
printf("%d\n",k);
printf("使用的盘块数是:\t");
printf("%d\n",m);
}
void help() /* 显示帮助信息 */
{
printf("1------dir----------------------查看当前目录文件列表(dir)\n");
printf("2------open---------------------打开文件(open + 空格 + 文件名)\n");
printf("3------ls-----------------------查看系统信息(ls)\n");
printf("4------mkdir--------------------创建目录(mkdir + 空格 + 目录名)\n");
printf("5------create-------------------创建文件(create + 空格 + 文件名)\n");
printf("6------read---------------------文件的的读(read +文件名)\n");
printf("7------write--------------------文件的写(write + 文件名)\n");
printf("8------close--------------------文件的的关闭(close + 文件名)\n");
printf("9------delete-------------------删除文件(delete + 空格 + 文件名)\n");
printf("10-----deldir-------------------删除目录(del + 空格 + 目录名)\n");
printf("11-----cd-----------------------进入当前目录下的指定目录(cd + 空格 + 目录名)\n");
printf("12-----cd..---------------------返回上一级目录(cd..)\n");
printf("13-----help---------------------显示帮助命令(help)\n");
printf("14-----logout-------------------退出文件模拟(logout)\n");
printf("15-----su-----------------------切换用户(su)\n");
printf("16-----CMode--------------------赋予用户权限(CMode)\n");
}
void main() /* 主函数 */
{
char tmp[10],com[10],tmp1[10];
int i, j=0,p,len=0;
FILE *fp;
printf("**************************欢迎使用模拟unix文件系统*******************\n");
if((fp=fopen("system","rb"))==NULL) /* 判断系统文件是否存在 */
{
format();
InitUserFileTable() ;
InitSystemFileTable();
InitActiveNode() ;
}
else
{
read_file(fp); /* 读取系统文件的内容 */
}
strcpy(cmd[1].com,"dir");
strcpy(cmd[2].com,"open");
strcpy(cmd[3].com,"ls");
strcpy(cmd[4].com,"mkdir");
strcpy(cmd[5].com,"create");
strcpy(cmd[6].com,"read");
strcpy(cmd[7].com,"write");
strcpy(cmd[8].com,"close");
strcpy(cmd[9].com,"delete");
strcpy(cmd[10].com,"deldir");
strcpy(cmd[11].com,"cd");
strcpy(cmd[12].com,"cd..");
strcpy(cmd[13].com,"help");
strcpy(cmd[14].com,"logout");
strcpy(cmd[15].com,"su") ;
strcpy(cmd[16].com,"CMode") ;
while(1)
{
while(!Login()) ;
while(1)
{
printf("[%s @ %s]#",user,cur_dir);
scanf("%s",com); /* 输入命令并且查找命令的相关操作 */
for(i=1;i<17;i++)
{
if(strcmp(com,cmd[i].com)==0)
{
p=i;
break;
}
}
if(i==17) /* 如果没有这个语句以后输入的命令都和第一次输入的效果一样 */
{
p=17; /* 随便的一个值 */
}
switch(p)
{
case 1: display_curdir(); /* 查看当前目录下的文件列表 */
break;
case 2: scanf("%s",tmp); /* 查看文件 */
open_file(tmp);
break;
case 3: display_sys(); /* 查看系统信息 */
break;
case 4: scanf("%s",tmp); /* 创建目录 */
create_dir(tmp);
break;
case 5: scanf("%s",tmp); /* 创建文件 */
create_file(tmp,80);
break;
case 6: scanf("%s",tmp);
readfile(tmp);
break;
case 7: scanf("%s",tmp);
writefile(tmp);
break;
case 8: scanf("%s",tmp);
closeFile(tmp);
break;
case 9: scanf("%s",tmp); /* 删除文件 */
for(i=0;i<512;i++) /* 判断文件是不是正规文件 */
{
j=root[i].i_num;
if(strcmp(tmp,root[i].file_name)==0 && (i_node[j].file_style)==1)
{
del_file(tmp);
break;
}
}
if(i==512)
{
printf("这个不是正规文件文件\n");
}
break;
case 10:
scanf("%s",tmp); /* 删除目录 */
del_dir(tmp);
break;
case 11: scanf("%s",tmp1); /* 进入当前目录下的指定目录 相当于进入目录 cd + 目录名 */
display_dir(tmp1);
break;
case 12: back_dir(); /* 返回上一级目录 */
break;
case 13: help();
break;
case 14: write_file(fp); /* 将磁盘利用信息写进系统文件,退出 */
break;
case 15: su() ;
break ;
case 16: scanf("%s",tmp1);
changeFileMode(tmp1) ;
break ;
default: printf("SORRY,没有这个命令\n");
break;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -