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

📄 unixfile.cpp

📁 模拟unix的文件系统(成组链接法).
💻 CPP
字号:
//Powered by 杭建 西安电子科技大学 030621班

#include "stdafx.h"
  
int style = 1;//文件的类型
char cur_dir[10] = "root"; //当前目录  

struct block{
	int n;//空闲的盘快的个数
     int free[50];//存放空闲盘快的地址
     int a;//模拟盘快是否被占用
}memory[20449];//假设每个内存块大小为512KB

struct block_super{
     int n;         //空闲的盘快的个数
     int free[50];  //存放空闲块最后一个单元内容对应内存块存放的是下一组空闲块的地址
}super_block;

struct dir{
	char file_name[10];   //文件名
     int  i_num;     //文件的结点号
     char dir_name[10];   //文件所在的目录
} root[640];

struct node{
     int file_style;    //i结点文件类型
     int file_length;   //i结点文件长度
     int file_address[100]; //i结点普通文件的物理地址
}i_node[640];

void format(){
     int i,j,k;
     super_block.n = 50;
     for(i=0;i<50;i++){ 
         super_block.free[i] = i;   //存放进入栈中的空闲块
     }

      for(i=0;i<640;i++){
	     for(j=0;j<100;j++){
             i_node[i].file_address[j] = -1;//文件地址
          }
	     i_node[i].file_length = -1;  //文件长度
          i_node[i].file_style = -1;  //文件类型
      }  

	 for(i=0;i<640;i++){//根目录区信息初始化
	     strcpy(root[i].file_name,"");
          root[i].i_num=-1;
          strcpy(root[i].dir_name,"");
      } 
	 for(i=0;i<20449;i++){//存储空间初始化
          memory[i].n = 0;  //必须有这个
          memory[i].a = 0;  //标记为没有使用    
		for(j=0;j<50;j++){
			memory[i].free[j] = -1;
          }
      }
	 for(i=0;i<20449;i++){    //将空闲块的信息用成组链接的方法写进每组的最后一个块存储空间初始化
	    if((i+1)%50 == 0){
		   k=i+1;
             for(j=0;j<50;j++){
		     	if(k<20450){
			     	memory[i].free[j] = k;//下一组空闲地址
                         memory[i].n++;  //下一组空闲个数,注意在memory[i].n++之前要给其赋初值
                         k++;
                    }
			     else{
				     memory[i].free[j]=-1;
                    }
             }
            continue;     //处理完用于存储下一组盘块信息的特殊盘块后,跳过本次循环
        }
     }
     printf("格式化完毕\n");
     printf("可以进行UNIX文件操作............\n");
     system("pause");
}

void create(){
	int i,j,m;
	char name[20],c;
	int tempLen;//保存文件大小

	printf("当前目录:%s\n请输入文件的类型:1-普通文件 2-目录文件:",cur_dir);
	scanf("%d",&style);//选择文件类型
	getchar();
	
	if(style == 1){//创建普通文件
		i = 0;

		printf("请输入文件名:");
		gets(name);//输入文件名

		while(strcmp(root[i].file_name,"")){//寻找没被占用的目录表项
			if(!strcmp(root[i].file_name,name)&&!strcmp(root[i].dir_name,cur_dir)){
			    printf("文件名重复!\n");
			    return;
			}
			if(i == 639){
			    printf("文件存放空间已满!\n");
			    return;
			}
		     i++;	

		}
		

		strcpy(root[i].file_name,name);//将文件名付给相应目录表项

		root[i].i_num = i;//将文件结点号付给相应目录表项
		strcpy(root[i].dir_name,cur_dir);//在目录表中记录文件按所在文件目录 

		printf("请输入文件的大小(KB):");
		scanf("%d",&tempLen);//输入文件大小
		getchar();
		i_node[i].file_length = tempLen;
		i_node[i].file_style = style;//文件类型赋值
		m = tempLen/512;
		if(tempLen%512 != 0) m++;//m为文件占用内存块数


		for(int p = 0;p < m;p++){//来自书上224页的算法
			if(super_block.n == 1){
				if(super_block.free[0] == 0){
					printf("储存空间不够!\n");
				     return;
			     }
				i_node[i].file_address[p] = super_block.free[0];
				memory[super_block.free[0]].a = 1;

				super_block.n = memory[super_block.free[0]].n;
				for(int q=0;q < 50;q++){
					super_block.free[q] = memory[super_block.free[0]].free[q];
					memory[super_block.free[0]].free[q] = -1;
				}
				memory[super_block.free[0]].n = 0;
			}
			else{
			     i_node[i].file_address[p] = super_block.free[0];
				memory[super_block.free[0]].a = 1;
				super_block.n--;
				for(j = 0;j < 49;j++){
					super_block.free[j] = super_block.free[j+1];
				}
			}

		}
		printf("建立普通文件成功!\n");
	}else if(style == 2){//创建目录文件,基本同普通文件的建立
		i = 0;

		printf("请输入目录文件名:");
		gets(name);

		while(strcmp(root[i].file_name,"")){
			if(!strcmp(root[i].file_name,name)&&!strcmp(root[i].dir_name,cur_dir)){
			    printf("文件名重复!\n");
			    return;
			}
			if(i == 639){
			    printf("文件存放空间已满!\n");
			    return;
			}
		     i++;	
		}
		

		strcpy(root[i].file_name,name);

		root[i].i_num = i;
		strcpy(root[i].dir_name,cur_dir);

		i_node[i].file_style = style;

		i_node[i].file_length = 512;//假设目录文件大小占一个内存块!
          if(super_block.n == 1){//算法同普通文件
				if(super_block.free[0] == 0){
					printf("储存空间不够!\n");
				     return;
			     }
				i_node[i].file_address[0] = super_block.free[0];
				memory[super_block.free[0]].a = 1;

				super_block.n = memory[super_block.free[0]].n;
				for(int q=0;q < 50;q++){
					super_block.free[q] = memory[super_block.free[0]].free[q];
					memory[super_block.free[0]].free[q] = -1;
				}
				memory[super_block.free[0]].n = 0;
		}else{
			 i_node[i].file_address[0] = super_block.free[0];
			 memory[super_block.free[0]].a = 1;
			 super_block.n--;
			 for(j = 0;j < 49;j++){
				super_block.free[j] = super_block.free[j+1];
			 }
		}

		printf("建立目录文件成功!\n");
	}else{
		printf("命令错误!\n");
		return;
	}
}

void deleteFile(){
	char name[20];
	char c;
     int i,p,m;

	printf("请输入要删除的文件名:");
     gets(name);

	for(i = 0;i < 640;i++){
		if(!strcmp(root[i].file_name,name)&&!strcmp(root[i].dir_name,cur_dir)) {
			printf("文件存在,你确定删除?y/n\n");
			c = getchar();
	          getchar();
			break;
		}
		if(!strcmp(root[i].file_name,"")) break;
	}
	if(i == 640||!strcmp(root[i].file_name,"")){
	     printf("文件不存在!\n");
		return;
	}

	if(c == 'n') return;
	else if(c != 'y'){
	    printf("命令错误!");
	    return;
	}

	if(i_node[i].file_style == 2){//如目录文件的内容不为空,则不能删除
		if(!strcmp(root[i].file_name,cur_dir)){
		          printf("你当前在此目录下,不能删除!\n");
		          return;
		}
	     for(int j = 0;j < 640;j++){	
			if(!strcmp(root[j].dir_name,name)) {
		     	printf("此目录文件不为空,不能删除!\n");
			     return;
		     }
			if(!strcmp(root[j].file_name,"")) break;
	     }	
	}

 


	if( i_node[root[i].i_num].file_length%512 == 0){
		m = i_node[root[i].i_num].file_length / 512;
	}else{
		m = i_node[root[i].i_num].file_length / 512 + 1;
	}//计算文件所占内存块数

	if(c == 'y'){//删除文件
		strcpy(root[i].file_name,"");//目录项重置
		strcpy(root[i].dir_name,"");//目录项重置
		for(p = 0;p < m;p++){//算法在书224页
			memory[i_node[root[i].i_num].file_address[p]].a = 0;
			if(super_block.n < 50){
				super_block.n++;
				super_block.free[super_block.n-1] = super_block.free[super_block.n-2];
				super_block.free[super_block.n-2] = i_node[root[i].i_num].file_address[p];
			}else{
				memory[i_node[root[i].i_num].file_address[p]].n = super_block.n;
				for(int q=0;q < 50;q++){
					memory[i_node[root[i].i_num].file_address[p]].free[q] = super_block.free[q];  
				}
				super_block.free[0] = i_node[root[i].i_num].file_address[p];
				super_block.n = 1;
			}
		}

		for(int j=0;j<100;j++){//对应结点的值重置
             i_node[root[i].i_num].file_address[j] = -1;
          }
		i_node[root[i].i_num].file_length = -1;
		i_node[root[i].i_num].file_style = -1;

		root[i].i_num = -1;//目录项重置

		printf("删除文件成功!");
	}else{
		return;
	}


}

void searchFile(){//查找文件
	char name[20];
	int i;
	printf("请输入你要查找的文件名:");
	gets(name);
     
	for(i = 0;i < 640;i++){
		if(!strcmp(root[i].file_name,name)&&!strcmp(root[i].dir_name,cur_dir)) {
			printf("文件存在,信息如下:\n");
			printf("文件名:%s 所在目录:%s 文件长度:%d ",root[i].file_name,root[i].dir_name,i_node[root[i].i_num].file_length);
			if(i_node[root[i].i_num].file_style == 1)
				printf("文件类型:普通文件\n");
			else
				printf("文件类型:目录文件\n");
			return;
		}
		if(!strcmp(root[i].file_name,"")) break;
	}
	if(i == 640||!strcmp(root[i].file_name,"")){
	     printf("文件不存在!\n");
	}

}

void list(){//列出当前文件目录下文件列表
	int i;
	int k = 0;
	for(i = 0;i < 640;i++){
		if(strcmp(root[i].file_name,"")){
			if(!strcmp(root[i].dir_name,cur_dir)){
				k++;
				printf("文件名:%s  所在目录:%s  文件长度:%d ",root[i].file_name,root[i].dir_name,i_node[root[i].i_num].file_length);
			     if(i_node[root[i].i_num].file_style == 1)
				    printf(" 文件类型:普通文件\n");
			     else
				    printf(" 文件类型:目录文件\n");
			}
		}else{
			if(k == 0) printf("该目录下暂无文件!\n");
		     break;
		}
	}
}

int main(){
   format();//格式化文件系统
   system("cls");
   printf("命令如下:\n\tc-创建文件或文件夹\n\td-删除文件或者文件夹\n\ts-查找文件或者文件夹\n\tl-显示当前目录文件列表\n\tf-格式化\n\tr-返回上级目录\n\tg-进入目录\n\tq-退出系统\n");

   char command;//命令
   int i;//计数器

   command = getchar();//获得命令
   getchar();
   while(true){
	   if(command == 'c'){
              create();//创建文件
		    system("pause");
	   }else if(command == 'd'){
	         deleteFile();//删除文件
		    system("pause");
	   }else if(command == 's'){
	         searchFile();//查找文件
		    system("pause");
	   }else if(command == 'l'){
	         list();//显示当前目录文件列表
              system("pause");
	   }else if(command == 'f'){
		    format();//格式化
	   }else if(command == 'r'){//返回上级目录
		    if(!strcmp(cur_dir,"root")) printf("已经是最顶目录!\n");
		    else{
			    for(i = 0;i < 640;i++){
		            if(!strcmp(root[i].file_name,cur_dir)) {
					  strcpy(cur_dir,root[i].dir_name);
					  printf("当前目录:%s\n",cur_dir);
					  break;
				  }
			    }
		    }
		    system("pause");
	   }else if(command == 'g'){//进入目录
		    char dName[20];
		    printf("请输入文件目录名:");
		    gets(dName);
          
		    for(i = 0;i < 640;i++){
			   if(!strcmp(root[i].file_name,dName)&&i_node[i].file_style == 2&&!strcmp(root[i].dir_name,cur_dir)) {
			     	strcpy(cur_dir,dName);
                         printf("进入目录:%s\n",cur_dir);
			          break;
		        }
			   if(!strcmp(root[i].file_name,"")) break;
	         }
	         if(i == 640||!strcmp(root[i].file_name,"")){
			    printf("文件目录不存在!当前目录:%s\n",cur_dir);
	         }
		    system("pause");
	   }else{//退出系统
		   if(command == 'q')
			   break;
		   else 
			   printf("命令错误!\n");
		   system("pause");
	   }
	   system("cls");
	   printf("命令如下:\n\tc-创建文件或文件夹\n\td-删除文件或者文件夹\n\ts-查找文件或者文件夹\n\tl-显示当前目录文件列表\n\tf-格式化\n\tr-返回上级目录\n\tg-进入目录\n\tq-退出系统\n");
	   command = getchar();
	   getchar();
   }

   return 0;

}

⌨️ 快捷键说明

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