现在的位置: 首页 > 综合 > 正文

linux文件系统模拟

2018年04月09日 ⁄ 综合 ⁄ 共 13690字 ⁄ 字号 评论关闭
  1. #include "stdio.h"  
  2. #include <stdlib.h>  
  3. //#include <conio.h>  
  4. #include <string.h> 
  5. #include"unistd.h" 
  6.  
  7. int physic[100];    //文件地址缓冲区 
  8. int style=1;     //文件的类型 
  9. char cur_dir[10]="root";  //当前目录   
  10.  
  11. struct command 
  12.     char com[10]; 
  13. }cmd[12]; 
  14.  
  15. struct block 
  16.     int n;      //空闲的盘快的个数 
  17.     int free[50];    //存放空闲盘快的地址 
  18.     int a;      //模拟盘快是否被占用 
  19. }memory[20449]; 
  20.  
  21. struct block_super 
  22.     int n;      //空闲的盘快的个数 
  23.     int free[50];    //存放进入栈中的空闲块 
  24.     int stack[50];    //存放下一组空闲盘快的地址 
  25. }super_block; 
  26.  
  27. struct node      //i结点信息 
  28.     int file_style;    //i结点 文件类型 
  29.     int file_length;   //i结点 文件长度 
  30.     int file_address[100];  //i结点 文件的物理地址 
  31. } i_node[640]; 
  32.  
  33. struct dir      //目录项信息 
  34.     char file_name[10];   //文件名 
  35.     int  i_num;     //文件的结点号 
  36.     char dir_name[10];   //文件所在的目录 
  37. } root[640]; 
  38.  
  39. void format()     //格式化 
  40.     int i,j,k; 
  41.     super_block.n=50; 
  42.     for(i=0;i<50;i++)     //超级块初始化 
  43.     {  
  44.         super_block.free[i]=i;   //存放进入栈中的空闲块 
  45.         super_block.stack[i]=50+i;  //存放下一组的盘块 
  46.     } 
  47.      
  48.     for(i=0;i<640;i++)     //i结点信息初始化 
  49.     { 
  50.         for(j=0;j<100;j++) 
  51.         { 
  52.             i_node[i].file_address[j]=-1;//文件地址 
  53.         } 
  54.         i_node[i].file_length=-1;  //文件长度 
  55.         i_node[i].file_style=-1;  //文件类型 
  56.     } 
  57.      
  58.     for(i=0;i<640;i++)     //根目录区信息初始化 
  59.     { 
  60.         strcpy(root[i].file_name,""); 
  61.         root[i].i_num=-1; 
  62.         strcpy(root[i].dir_name,""); 
  63.     }  
  64.     for(i=0;i<20449;i++)     //存储空间初始化   
  65.     { 
  66.         memory[i].n=0;      //必须有这个 
  67.         memory[i].a=0;       
  68.         for(j=0;j<50;j++) 
  69.         { 
  70.             memory[i].free[j]=-1; 
  71.         } 
  72.     } 
  73.     for(i=0;i<20449;i++)    //将空闲块的信息用成组链接的方法写进每组的最后一个块中 
  74.     {         //存储空间初始化 
  75.          
  76.         if((i+1)%50==0) 
  77.         { 
  78.             k=i+1; 
  79.             for(j=0;j<50;j++) 
  80.             { 
  81.                 if(k<20450) 
  82.                 { 
  83.                     memory[i].free[j]=k;//下一组空闲地址 
  84.                     memory[i].n++;  //下一组空闲个数   注意在memory[i].n++之前要给其赋初值 
  85.                     k++; 
  86.                 } 
  87.                 else 
  88.                 { 
  89.                     memory[i].free[j]=-1; 
  90.                 } 
  91.             } 
  92.             memory[i].a=0;    //标记为没有使用 
  93.             continue;     //处理完用于存储下一组盘块信息的特殊盘块后,跳过本次循环 
  94.         } 
  95.         for(j=0;j<50;j++) 
  96.         { 
  97.             memory[i].free[j]=-1; 
  98.         } 
  99.         memory[i].n=0;   
  100.     } 
  101.     printf("已经初始化完毕\n"); 
  102.     printf("进入linux文件系统模拟............\n"); 
  103.  
  104. void write_file(FILE *fp)    //将信息读入系统文件中 
  105.     int i; 
  106.     fp=fopen("system","wb"); 
  107.     for(i=0;i<20449;i++) 
  108.     { 
  109.         fwrite(&memory[i],sizeof(struct block),1,fp); 
  110.     } 
  111.     fwrite(&super_block,sizeof(struct block_super),1,fp); 
  112.      
  113.     for(i=0;i<640;i++) 
  114.     { 
  115.         fwrite(&i_node[i],sizeof(struct node),1,fp); 
  116.     } 
  117.     for(i=0;i<640;i++) 
  118.     { 
  119.         fwrite(&root[i],sizeof(struct dir),1,fp); 
  120.     } 
  121.     fclose(fp); 
  122.  
  123. void read_file(FILE *fp)   //读出系统文件的信息 
  124.     int i; 
  125.     fp=fopen("system","rb"); 
  126.     for(i=0;i<20449;i++) 
  127.     { 
  128.         fread(&memory[i],sizeof(struct block),1,fp); 
  129.     } 
  130.      
  131.     fread(&super_block,sizeof(struct block_super),1,fp); 
  132.      
  133.     for(i=0;i<640;i++) 
  134.     { 
  135.         fread(&i_node[i],sizeof(struct node),1,fp); 
  136.     } 
  137.      
  138.     for(i=0;i<640;i++) 
  139.     { 
  140.         fread(&root[i],sizeof(struct dir),1,fp); 
  141.     }  
  142.     fclose(fp); 
  143.  
  144. void callback(int length)    //回收磁盘空间 
  145.     int i,j,k,m,q=0; 
  146.     for(i=length-1;i>=0;i--) 
  147.     { 
  148.         k=physic[i];     //需要提供要回收的文件的地址 
  149.         m=49-super_block.n;    //回收到栈中的哪个位置 
  150.         if(super_block.n==50)   //注意 当super_block.n==50时 m=-1;的值 
  151.         {        //super_block.n==50的时候栈满了,要将这个栈中的所有地址信息写进下一个地址中 
  152.             for(j=0;j<50;j++) 
  153.             { 
  154.                 memory[k].free[j]=super_block.free[j]; 
  155.             } 
  156.             super_block.n=0;  
  157.             memory[k].n=50; 
  158.         } 
  159.         memory[k].a=0;  
  160.         if(m==-1) 
  161.         { 
  162.             m=49;      //将下一个文件地址中的盘块号回收到栈底中,这个地址中存放着刚才满栈的地址的信息  
  163.         } 
  164.         super_block.free[m]=physic[i]; //将下一个文件地址中的盘块号回收到栈中 
  165.         super_block.n++; 
  166.     } 
  167.  
  168. void allot(int length)     //分配空间 
  169.     int i,j,k,m,p; 
  170.     for(i=0;i<length;i++) 
  171.     { 
  172.         k=50-super_block.n;    //超级块中表示空闲块的指针 
  173.         m=super_block.free[k];   //栈中的相应盘块的地址 
  174.         p=super_block.free[49];   //栈中的最后一个盘块指向的地址 
  175.         if(m==-1||memory[p].a==1)  //检测是否还有下一组盘块 
  176.         { 
  177.             printf("内存不足,不能够分配空间\n"); 
  178.             callback(length); 
  179.             break
  180.         } 
  181.         if(super_block.n==1) 
  182.         {   
  183.             memory[m].a=1;    //将最后一个盘块分配掉 
  184.             physic[i]=m; 
  185.             super_block.n=0;    
  186.             for(j=0;j<memory[m].n;j++) //从最后一个盘块中取出下一组盘块号写入栈中 
  187.             {  
  188.                 super_block.free[j]=memory[m].free[j]; 
  189.                 super_block.n++; 
  190.             } 
  191.             continue;     //要跳过这次循环,下面的语句在IF中已经执行过 
  192.         } 
  193.         physic[i]=m;     //栈中的相应盘块的地址写进 文件地址缓冲区 
  194.         memory[m].a=1;   
  195.         super_block.n--; 
  196.     } 
  197.  
  198. void create_file(char filename[],int length) //创建文件 
  199.     int i,j; 
  200.     for(i=0;i<640;i++) 
  201.     { 
  202.         if(strcmp(filename,root[i].file_name)==0) 
  203.         { 
  204.             printf("文件已经存在,不允许建立重名的文件\n"); 
  205.             return
  206.         } 
  207.     } 
  208.     for(i=0;i<640;i++) 
  209.     { 
  210.         if(root[i].i_num==-1) 
  211.         { 
  212.             root[i].i_num=i; 
  213.             strcpy(root[i].file_name,filename); 
  214.             strcpy(root[i].dir_name,cur_dir);  //把当前目录名 给新建立的文件 
  215.             i_node[i].file_style=style; 
  216.             i_node[i].file_length=length; 
  217.             allot(length); 
  218.             for(j=0;j<length;j++) 
  219.             { 
  220.                 i_node[i].file_address[j]=physic[j]; 
  221.             } 
  222.             break
  223.         } 
  224.     } 
  225.  
  226. void create_dir(char filename[])    //创建目录 
  227.     style=0;         //0代表文件类型是目录文件 
  228.     create_file(filename,4); 
  229.     style=1;         //用完恢复初值,因为全局变量,否则 
  230. void del_file(char filename[])     //删除文件 
  231.     int i,j,k; 
  232.     for(i=0;i<640;i++) 
  233.     { 
  234.          
  235.         if(strcmp(filename,root[i].file_name)==0)    
  236.         {  
  237.             k=root[i].i_num; 
  238.             for(j=0;j<i_node[k].file_length;j++) 
  239.             { 
  240.                 physic[j]=i_node[k].file_address[j]; 
  241.             } 
  242.             callback(i_node[k].file_length); //调用 回收函数 
  243.             for(j=0;j<100;j++)     //删除文件后要将文件属性和目录项的各个值恢复初值 
  244.             { 
  245.                 i_node[k].file_address[j]=-1; //地址恢复初值 
  246.             } 
  247.             strcpy(root[i].file_name,"");  //文件名恢复初值 
  248.             root[i].i_num=-1;     //目录项的I结点信息恢复初值 
  249.             strcpy(root[i].dir_name,"");  //目录项的文件目录信息恢复初值 
  250.             i_node[k].file_length=-1;   //文件长度恢复 
  251.             i_node[k].file_style=-1;   //文件类型恢复初值 
  252.             break
  253.         }  
  254.     } 
  255.     if(i==640) 
  256.     { 
  257.         printf("不存在这个文件\n"); 
  258.     }  
  259.  
  260. void del_dir(char filename[])     //删除目录   需要判断目录下时候为空,不为空就不删除 
  261.     int i,j,k; 
  262.     for(i=0;i<640;i++)       //还要加条件判断要删除的目录是不是当前目录 
  263.     { 
  264.         k=root[i].i_num;      //找到目录名字 
  265.         if( strcmp(root[i].file_name,filename)==0 && strcmp(cur_dir,filename)!=0 && (i_node[k].file_style)==0 )  
  266.         { 
  267.              
  268.             for(j=0;j<640;j++) 
  269.             { 
  270.                 if(strcmp(filename,root[j].dir_name)==0) 
  271.                 { 
  272.                     printf("目录不为空不能直接删除\n"); 
  273.                     break
  274.                 } 
  275.             } 
  276.             if(j==640) 
  277.             { 
  278.                 del_file(filename); 
  279.                 break
  280.             } 
  281.              
  282.             break
  283.         } 
  284.     } 
  285.     if(i==640) 
  286.     { 
  287.         printf("这个不是目录文件 或者不存在这个目录,或者你要删除的是当前目录\n"); 
  288.     }  
  289.      
  290. }  
  291. void display_curdir()         //显示当前目录下的文件列表 
  292.     int i,k; 
  293.     printf("\t\t文件名字  文件类型  文件长度  所属目录\n"); 
  294.     for(i=0;i<640;i++) 
  295.     { 
  296.         if(strcmp(cur_dir,root[i].dir_name)==0)   //查询文件中 所在目录信息和当前目录信息相同的数据 
  297.         { 
  298.             k=root[i].i_num; 
  299.             printf("\t\t  %s\t",root[i].file_name);  //文件名 
  300.             printf("\t%d\t",i_node[k].file_style);  //文件的类型 
  301.             printf("%d\t",i_node[k].file_length);  //文件的长度 
  302.             printf("%s\n",root[i].dir_name);   //文件所在的目录 
  303.         } 
  304.     } 
  305.  
  306. void display_dir(char filename[])     //进入指定的目录   
  307.     int i,k;   
  308.     for(i=0;i<640;i++) 
  309.     { 
  310.         k=root[i].i_num;       //判断文件类型是不是目录类型 
  311.         if((strcmp(filename,root[i].file_name)==0) && (i_node[k].file_style==0))     
  312.         { 
  313.             strcpy(cur_dir,filename);    //将要进入的指定目录设置为当前目录  赋值不要反了strcpy(目的,源) 
  314.             break
  315.         } 
  316.     } 
  317.     if(i==640) 
  318.     { 
  319.         printf("没有这个目录\n"); 
  320.     } 
  321. void open_file(char filename[])        //打开文件 
  322.     int i,j,k; 
  323.     printf("\t\t文件名字  文件类型  文件长度  所属目录\n"); 
  324.     for(i=0;i<640;i++) 
  325.     { 
  326.         k=root[i].i_num; 
  327.         if(strcmp(filename,root[i].file_name)==0 && (i_node[k].file_style==1)) 
  328.         { 
  329.             printf("\t\t  %s\t",root[i].file_name);   //文件名 
  330.             printf("\t%d\t",i_node[k].file_style);   //文件的类型 
  331.             printf("%d\t",i_node[k].file_length);   //文件的长度 
  332.             printf("%s\n",root[i].dir_name);    //文件所在的目录 
  333.             printf("\t\t文件占用的物理地址\n"); 
  334.             for(j=0;j<i_node[k].file_length;j++)   //显示物理地址 
  335.             {   
  336.                 printf("%d  ",i_node[k].file_address[j]); //文件具体占用的盘块号 
  337.             } 
  338.             printf("\n"); 
  339.             break
  340.         }  
  341.     } 
  342.     if(i==640) 
  343.     { 
  344.         printf("没有这个文件 或者这个文件不是正规文件\n"); 
  345.     } 
  346.  
  347. void back_dir()         //返回上一级目录 
  348.     int  i,k; 
  349.     for(i=0;i<640;i++)       //查询和当前目录名相同的目录文件名 
  350.     { 
  351.         k=root[i].i_num; 
  352.         if(strcmp(cur_dir,root[i].file_name)==0 && (i_node[k].file_style==0))   
  353.         { 
  354.             strcpy(cur_dir,root[i].dir_name); //将查询到的目录文件名  所在的目录赋值给当前目录 
  355.         } 
  356.     } 
  357. void display_sys()        //显示系统信息(磁盘使用情况) 
  358.     int i,m,k=0; 
  359.     for(i=0;i<20449;i++) 
  360.     { 
  361.         if(memory[i].a==0) 
  362.             k++; 
  363.     } 
  364.     m=20449-k; 
  365.     printf("空闲的盘块数是:\t"); 
  366.     printf("%d\n",k); 
  367.     printf("使用的盘块数是:\t"); 
  368.     printf("%d\n",m); 
  369.  
  370. void help()          //显示帮助信息 
  371.     printf("注意:创建的文件长度 < 100\n\n"); //说明文件 
  372.     printf("0.初始化-------------------------format\n"); 
  373.     printf("1.查看当前目录文件列表-----------dir\n"); 
  374.     printf("2.创建文件---------------------create-----(create  + 空格 + 文件名 + 文件长度)  \n"); 
  375.     printf("3.打开文件-----------------------cat-----(cat + 空格 + 文件名)  \n"); 
  376.     printf("4.删除文件-----------------------del-----(del + 空格 + 文件名) \n"); 
  377.     printf("5.创建目录-----------------------md------(md  + 空格 + 目录名)  \n"); 
  378.     printf("6.删除目录-----------------------deldir--(del + 空格 + 目录名)\n"); 
  379.     printf("7.进入当前目录下的指定目录-------cd--------(cd + 空格 + 目录名)\n"); 
  380.     printf("8.返回上一级目录-----------------cd..  \n"); 
  381.     printf("9.查看系统信息-------------------ls    \n"); 
  382.     printf("10.显示帮助命令-----------------help  \n"); 
  383.     printf("11.退出文件模拟------------------exit  \n"); 
  384. void main()          //主函数 
  385.     char tmp[10],com[10],tmp1[10],k; 
  386.     struct command tmp2[10]; 
  387.     int i, j=0,p,len=0; 
  388.     FILE *fp; 
  389.     help(); 
  390.     strcpy(cmd[0].com,"format");    //将各个命令存进命令表 
  391.     strcpy(cmd[1].com,"dir"); 
  392.     strcpy(cmd[2].com,"cat"); 
  393.     strcpy(cmd[3].com,"ls"); 
  394.     strcpy(cmd[4].com,"md"); 
  395.   
  396. strcpy(cmd[5].com,"create"); 
  397.     strcpy(cmd[6].com,"del"); 
  398.     strcpy(cmd[7].com,"deldir"); 
  399.     strcpy(cmd[8].com,"cd"); 
  400.     strcpy(cmd[9].com,"cd.."); 
  401.     strcpy(cmd[10].com,"help"); 
  402.     strcpy(cmd[11].com,"exit"); 
  403.     if((fp=fopen("system","rb"))==NULL)   //判断系统文件是否存在 
  404.     { 
  405.         printf("can not open file\n"); 
  406.         printf("format the disk  Y / N \n"); 
  407.         scanf("%c",&k); 
  408.         if(k=='y'
  409.             format();  
  410.     } 
  411.     else 
  412.     { 
  413.         read_file(fp);       //读取系统文件的内容 
  414.     } 
  415.      
  416.     while(1) 
  417.     { 
  418.         j=0;         //必须重新给恢复0否则出错 
  419.         strcpy(tmp,cur_dir); 
  420.         while(strcmp(tmp,"root")!=0) 
  421.         { 
  422.             for(i=0;i<640;i++) 
  423.             { 
  424.                 p=root[i].i_num; 
  425.                 if(strcmp(tmp,root[i].file_name)==0 && (i_node[p].file_style==0)) 
  426.                 { 
  427.                     strcpy(tmp2[j].com,tmp); 
  428.                     j++; 
  429.                     strcpy(tmp,root[i].dir_name); 
  430.                 } 
  431.             } 
  432.         } 
  433.          
  434.         strcpy(tmp2[j].com,tmp); 
  435.         for(i=j;i>=0;i--) 
  436.         { 
  437.             printf("%s/",tmp2[i].com);  
  438.         } 
  439.          
  440.         scanf("%s",com);       //输入命令并且查找命令的相关操作 
  441.         for(i=0;i<12;i++)        
  442.         { 
  443.             if(strcmp(com,cmd[i].com)==0) 
  444.             { 
  445.                 p=i; 
  446.                 break
  447.             } 
  448.         } 
  449.         if(i==12)         //如果没有这个语句以后输入的命令都和第一次输入的效果一样 
  450.         { 
  451.             p=13; //随便的一个值 
  452.         } 
  453.         switch(p) 
  454.         { 
  455.         case 0: format();       //初始化 
  456.             break
  457.         case 1: display_curdir();     //查看当前目录下的文件列表       
  458.             break
  459.         case 2: scanf("%s",tmp);     //查看文件  
  460.             open_file(tmp);   
  461.             break
  462.         case 3: display_sys();      //查看系统信息 
  463.             break
  464.         case 4:scanf("%s",tmp);      //创建目录     
  465.             create_dir(tmp);   
  466.             break
  467.         case 5: scanf("%s",tmp);     //创建文件  
  468.             scanf("%d",&len); 
  469.             create_file(tmp,len);   
  470.             break
  471.         case 6: scanf("%s",tmp);     //删除文件 
  472.             for(i=0;i<640;i++)     //判断文件是不是正规文件 
  473.             { 
  474.                 j=root[i].i_num; 
  475.                 if(strcmp(tmp,root[i].file_name)==0 && (i_node[j].file_style)==1) 
  476.                 { 
  477.                     del_file(tmp); 
  478.                     break
  479.                 } 
  480.             } 
  481.             if(i==640) 
  482.             { 
  483.                 printf("这个不是正规文件文件\n"); 
  484.             }      
  485.             break
  486.         case 7:  
  487.             scanf("%s",tmp);     //删除目录 
  488.             del_dir(tmp);    
  489.             break
  490.         case 8: scanf("%s",tmp1);     //进入当前目录下的指定目录   相当于进入目录  cd  +  目录名 
  491.             display_dir(tmp1); 
  492.             break
  493.         case 9: back_dir();       //返回上一级目录 
  494.             break
  495.         case 10:help(); 
  496.             break
  497.         case 11:write_file(fp);      //将磁盘利用信息写进系统文件,退出 
  498.             return
  499.         default:printf("没有这个命令\n"); 
  500.             break
  501.         } 
  502.     } 
  503. }  

 

 

抱歉!评论已关闭.