操作系统课程设计(二)简单文件系统实现

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #define DIR_LENGTH  1024     /*路径最长可达100字节*/
  5. #define MAX_WRITE 1024*128    /*写入文字可达128k字节*/      
  6. #define MEM_D_SIZE 1024*1024    /*1M磁盘空间*/
  7. #define DISKSIZE 1024     /*磁盘快的大小 1K*/
  8. #define MSD   5      /*最大子目录数 5 (类似五叉树)*/
  9. #define DISK_NUM MEM_D_SIZE/DISKSIZE  /*磁盘快数目 1024=1M/1K*/
  10. #define FATSIZE  DISK_NUM*sizeof(struct fatitem) /*FAT表大小 8K=8192B (理想应该是 1.5K)*/
  11. #define MOFN  5      /*最大文件打开数 5 (即除根以外最大深度为5)*/
  12. #define ROOT_DISK_NO FATSIZE/DISKSIZE+1  /*根目录起始盘快号 9*/
  13. #define ROOT_DISK_SIZE sizeof(struct direct)/*根目录大小 196*/ 
  14. /*---------------FAT表项结构-----------------------*/
  15. struct fatitem  /* size 8*/
  16. {
  17.  int item;  /*存放文件下一个磁盘的指针*/
  18.  char em_disk; /*磁盘块是否空闲标志位 0 空闲*/
  19. };
  20. /*-------------------目录项结构------------------------*/
  21. struct direct  /* size 196*/
  22. {
  23.  /*-----文件控制快信息-----*/
  24.  struct FCB
  25.  {
  26.    char name[9];  /*文件/目录名 8位*/
  27.    char property;  /*属性 1位目录 0位普通文件*/
  28.    int size;   /*文件/目录字节数(原注释位盘块数)*/
  29.    int firstdisk;  /*文件/目录 起始盘块号*/
  30.    int next;   /*子目录起始盘块号*/
  31.    int sign;   /*1是根目录 0不是根目录*/
  32.  }directitem[MSD+2];
  33. };
  34. /*------------------文件打开表项结构--------------------------*/
  35. struct opentable   /* size 104*/
  36. {
  37.  struct openttableitem /* size 20*/
  38.  {
  39.   char name[9]; /*文件名*/
  40.   int firstdisk; /*起始盘块号*/ 
  41.   int size;  /*文件的大小*/
  42.  }openitem[MOFN];
  43.  int cur_size;  /*当前打文件的数目*/
  44. };
  45. /*-------------------------------------------------------------------*/
  46. struct fatitem *fat;   /*FAT表*/
  47. struct direct *root;   /*根目录*/
  48. struct direct *cur_dir;   /*当前目录*/
  49. struct opentable u_opentable; /*文件打开表*/
  50. int  fd=-1;     /*文件打开表的序号*/
  51. char *bufferdir;    /*记录当前路径的名称*/
  52. char *fdisk;     /*虚拟磁盘起始地址*/
  53. void initfile();
  54. void   format();
  55. void enter();
  56. void     halt();
  57. int create(char *name);
  58. int   open(char *name);
  59. int  close(char *name);
  60. int write(int fd,char *buf,int len);
  61. int  read(int fd,char *buf);
  62. int   del(char *name);
  63. int mkdir(char *name);
  64. int rmdir(char *name);
  65. void dir();
  66. int cd(char *name);
  67. void print();
  68. void show();
  69. /*----------------------------------------------------------------------------------------------*/
  70. /*------------------------------------------初始化文件系统--------------------------------------*/
  71. void initfile()
  72. {
  73.  fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/
  74.  format();
  75.  free(fdisk);
  76. }
  77. /*----------------------------------------------------------------------------------------------*/
  78. /*------------------------------------------格式化----------------------------------------------*/
  79. void format()
  80. {
  81.  int i;
  82.  FILE *fp;
  83.  fat = (struct fatitem *)(fdisk+DISKSIZE); /*计算FAT表地址(为什么向后偏移 1k)*/
  84.  /*-----初始化FAT表------------*/
  85.  fat[0].item=-1;  /*引导块*/
  86.  fat[0].em_disk='1';
  87.  for(i=1;i<ROOT_DISK_NO-1;i++) /*存放 FAT表的磁盘块号*/
  88.  {
  89.   fat[i].item=i+1;
  90.   fat[i].em_disk='1';  
  91.  }
  92.  fat[ROOT_DISK_NO-1].item=-1;
  93.  fat[ROOT_DISK_NO-1].em_disk='1';
  94.  fat[ROOT_DISK_NO].item=-1;  /*存放根目录的磁盘块号*/
  95.  fat[ROOT_DISK_NO].em_disk='1';
  96.  for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)
  97.  {
  98.   fat[i].item = -1;
  99.   fat[i].em_disk = '0';  
  100.  }
  101.  /*-----------------------------------------------*/
  102.  root = (struct direct *)(fdisk+DISKSIZE+FATSIZE); /*根目录的地址*/
  103.  /*初始化目录*/
  104.  /*---------指向当前目录的目录项---------*/
  105.  root->directitem[0].sign = 1;
  106.  root->directitem[0].firstdisk = ROOT_DISK_NO;
  107.  strcpy(root->directitem[0].name,".");
  108.  root->directitem[0].next = root->directitem[0].firstdisk;
  109.  root->directitem[0].property = '1';
  110.  root->directitem[0].size = ROOT_DISK_SIZE;
  111.  /*-------指向上一级目录的目录项---------*/
  112.  root->directitem[1].sign = 1;
  113.  root->directitem[1].firstdisk = ROOT_DISK_NO;
  114.  strcpy(root->directitem[1].name,"..");
  115.  root->directitem[1].next = root->directitem[0].firstdisk;
  116.  root->directitem[1].property = '1';
  117.  root->directitem[1].size = ROOT_DISK_SIZE;
  118.  for(i=2;i<MSD+2;i++) /*-子目录初始化为空-*/
  119.  {
  120.   root->directitem[i].sign = 0;
  121.   root->directitem[i].firstdisk = -1;
  122.   strcpy(root->directitem[i].name,"");
  123.   root->directitem[i].next = -1;
  124.   root->directitem[i].property = '0';
  125.   root->directitem[i].size = 0;  
  126.  }
  127.  if((fp = fopen("disk.dat","wb"))==NULL)
  128.  {
  129.   printf("Error:/n Cannot open file /n");
  130.   return;
  131.  }
  132.  if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1) /*把虚拟磁盘空间保存到磁盘文件中*/  
  133.  {
  134.   printf("Error:/n File write error! /n");
  135.  }
  136.  fclose(fp);
  137. }
  138. /*----------------------------------------------------------------------------------------------*/
  139. /*--------------------------------进入文件系统--------------------------------------------------*/
  140. void enter()
  141. {
  142.      FILE *fp;
  143.      int i;
  144.      fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/
  145.      if((fp=fopen("disk.dat","rb"))==NULL)
  146.      {
  147.           printf("Error:/nCannot open file/n");
  148.           return;                                
  149.      }
  150.      if(!fread(fdisk,MEM_D_SIZE,1,fp))  /*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/    
  151.   {
  152.           printf("Error:/nCannot read file/n");
  153.           exit(0);  
  154.   }
  155.      fat = (struct fatitem *)(fdisk+DISKSIZE);  /*找到FAT表地址*/
  156.      root = (struct direct *)(fdisk+DISKSIZE+FATSIZE);/*找到根目录地址*/
  157.      fclose(fp);
  158.      /*--------------初始化用户打开表------------------*/
  159.      for(i=0;i<MOFN;i++)
  160.      {
  161.           strcpy(u_opentable.openitem[i].name,"");
  162.           u_opentable.openitem[i].firstdisk = -1;
  163.           u_opentable.openitem[i].size = 0;              
  164.      }
  165.      u_opentable.cur_size = 0;
  166.      
  167.      cur_dir = root; /*当前目录为根目录*/
  168.      bufferdir = (char *)malloc(DIR_LENGTH*sizeof(char));
  169.      strcpy(bufferdir,"Root:"); /*显示根目录为E:*/ 
  170. }
  171. /*----------------------------------------------------------------------------------------------*/
  172. /*------------------------------------退出文件系统----------------------------------------------*/
  173. void halt()
  174. {
  175.      FILE *fp;
  176.      int i;
  177.      if((fp=fopen("disk.dat","wb"))==NULL)
  178.      {
  179.           printf("Error:/nCannot open file/n");
  180.           return;                                
  181.      }
  182.      if(!fwrite(fdisk,MEM_D_SIZE,1,fp)) /*把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */
  183.   {
  184.   printf("Error:/nFile write error!/n");
  185.   }
  186.      fclose(fp);
  187.      
  188.      free(fdisk);
  189.   free(bufferdir);
  190.      
  191.      for(i=0;i<MOFN;i++) /*撤销用户打开表 (好像没有必要,系统自动会回收)*/
  192.      {
  193.           strcpy(u_opentable.openitem[i].name,"");
  194.           u_opentable.openitem[i].firstdisk = 0;
  195.           u_opentable.openitem[i].size = 0;              
  196.      }
  197.      u_opentable.cur_size = 0; /*用户打开文件数清零*/
  198.      
  199.      return;
  200.      
  201. }
  202. /*----------------------------------------------------------------------------------------------*/
  203. /*----------------------------------------创建文件----------------------------------------------*/
  204. int create(char *name)
  205. {
  206.     int i,j;
  207.         
  208.     if(strlen(name)>8) /*文件名大于 8位*/
  209.            return(-1);
  210.            
  211.     for(i=2;i<MSD+2;i++) /*找到第一个空闲子目录*/
  212.     {
  213.            if(cur_dir->directitem[i].firstdisk==-1)
  214.                      break;             
  215.     }
  216.     
  217.     for(j=2;j<MSD+2;j++) /*检查创建文件是否与已存在的文件重名*/
  218.     {
  219.            if(!strcmp(cur_dir->directitem[j].name,name))
  220.                      break;   
  221.     }
  222.     
  223.     if(i>=MSD+2) /*无空目录项*/
  224.             return(-2);
  225.     if(u_opentable.cur_size>=MOFN) /*打开文件太多(第五层)*/
  226.             return(-3); 
  227.     if(j<MSD+2)     /*文件已经存在*/
  228.             return(-4);
  229.             
  230.     for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*找到空闲盘块 j 后退出*/
  231.     {
  232.            if(fat[j].em_disk=='0')
  233.                      break;
  234.     }
  235.  if(j>=DISK_NUM)
  236.   return(-5);
  237.     fat[j].em_disk = '1';  /*将空闲块置为已经分配*/
  238.     /*-----------填写目录项-----------------*/
  239.     strcpy(cur_dir->directitem[i].name,name);
  240.     cur_dir->directitem[i].firstdisk = j;
  241.     cur_dir->directitem[i].size = 0;
  242.     cur_dir->directitem[i].next = j;
  243.     cur_dir->directitem[i].property = '0';
  244.  /*cur_dir->directitem[i].sign  丢失*/
  245.     /*---------------------------------*/
  246.     fd = open(name); /*打开所创建的文件*/
  247.     return 0;
  248. }
  249. /*----------------------------------------------------------------------------------------------*/
  250. /*----------------------------------------打开文件----------------------------------------------*/
  251. int open(char *name)
  252. {
  253.     int i, j;
  254.        
  255.     for(i=2;i<MSD+2;i++) /*文件是否存在*/
  256.     {
  257.            if(!strcmp(cur_dir->directitem[i].name,name))
  258.                      break;   
  259.     }
  260.     
  261.     if(i>=MSD+2) /*文件不存在*/
  262.             return(-1);
  263.  /*--------是文件还是目录-----------------------*/  
  264.  if(cur_dir->directitem[i].property=='1')/*是目录,不可打开读写*/
  265.    return(-4);
  266.     /*--------文件是否打开-----------------------*/        
  267.     for(j=0;j<MOFN;j++)
  268.     {
  269.            if(!strcmp(u_opentable.openitem[j].name,name))
  270.       break;
  271.     } 
  272.      if(j<MOFN)  /*文件已经打开*/
  273.             return(-2);
  274.             
  275.                    
  276.     if(u_opentable.cur_size>=MOFN) /*文件打开太多*/
  277.             return(-3); 
  278.     /*--------查找一个空闲用户打开表项-----------------------*/    
  279.     for(j=0;j<MOFN;j++)
  280.     {
  281.            if(u_opentable.openitem[j].firstdisk==-1)
  282.                      break;    
  283.     }
  284.     /*--------------填写表项的相关信息------------------------*/
  285.     u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk;
  286.     strcpy(u_opentable.openitem[j].name,name);
  287.     u_opentable.openitem[j].size = cur_dir->directitem[i].size;
  288.     u_opentable.cur_size++;
  289.     /*----------返回用户打开表表项的序号--------------------------*/
  290.     return(j);
  291. }
  292. /*----------------------------------------------------------------------------------------------*/
  293. /*----------------------------------------关闭文件----------------------------------------------*/
  294. int close(char *name)
  295. {
  296.     int i;
  297.     for(i=0;i<MOFN;i++)
  298.     {
  299.            if(!strcmp(u_opentable.openitem[i].name,name))
  300.                      break;   
  301.     } 
  302.     if(i>=MOFN)  /*--文件没有打开-*/  
  303.             return(-1); 
  304.     /*-----------清空该文件的用户打开表项的内容---------------------*/
  305.     strcpy(u_opentable.openitem[i].name,"");
  306.     u_opentable.openitem[i].firstdisk = -1;
  307.     u_opentable.openitem[i].size = 0;
  308.     u_opentable.cur_size--;
  309.     
  310.     fd = -1; /*文件打开表的序号为 -1 */
  311.     return 0;
  312. }
  313. /*----------------------------------------------------------------------------------------------*/
  314. /*----------------------------------------写文件------------------------------------------------*/
  315. int write(int fd, char *buf, int len)
  316. {
  317.  char *first;
  318.  int item, i, j, k;
  319.  int ilen1, ilen2, modlen, temp;
  320.  /*----------用 $ 字符作为空格 # 字符作为换行符-----------------------*/
  321.  char Space = 32; /*SPACE的ASCII码值*/
  322.  char Endter= '/n';
  323.  for(i=0;i<len;i++)
  324.  {
  325.   if(buf[i] == '$'/*用 $ 字符作为空格*/
  326.    buf[i] = Space;
  327.   else if(buf[i] == '#')
  328.    buf[i] = Endter;
  329.  }
  330.  /*----------读取用户打开表对应表项第一个盘块号-----------------------*/
  331.  item = u_opentable.openitem[fd].firstdisk;
  332.  /*-------------找到当前目录所对应表项的序号-------------------------*/
  333.  for(i=2;i<MSD+2;i++)
  334.  {
  335.    if(cur_dir->directitem[i].firstdisk==item)
  336.       break;
  337.  }
  338.  temp = i; /*-存放当前目录项的下标-*/
  339.  /*------找到的item 是该文件的最后一块磁盘块-------------------*/
  340.  while(fat[item].item!=-1) 
  341.  {
  342.   item =fat[item].item; /*-查找该文件的下一盘块--*/
  343.  }
  344.  /*-----计算除该文件的最末地址-------*/
  345.  first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE;
  346.  /*-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------*/
  347.  if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len)
  348.  {
  349.    strcpy(first,buf);
  350.    u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len;
  351.    cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;
  352.  }
  353.  else
  354.  {
  355.    for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++)
  356.    {/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/ 
  357.     first[i] = buf [i];
  358.    }
  359.    /*-----计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储-------*/
  360.    ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);
  361.    ilen2 = ilen1/DISKSIZE;  
  362.    modlen = ilen1%DISKSIZE;
  363.    if(modlen>0)
  364.       ilen2 = ilen2+1; /*--还需要多少块磁盘块-*/
  365.  /*调试时特别注意*/
  366.    for(j=0;j<ilen2;j++)
  367.    {
  368.       for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)/*寻找空闲磁盘块*/
  369.       {
  370.        if(fat[i].em_disk=='0')
  371.          break;
  372.       }
  373.       if(i>=DISK_NUM) /*--如果磁盘块已经分配完了-*/
  374.        return(-1);
  375.       first = fdisk+i*DISKSIZE; /*--找到的那块空闲磁盘块的起始地址-*/
  376.       if(j==ilen2-1) /*--如果是最后要分配的一块-*/
  377.       {
  378.        for(k=0;k<len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)-j*DISKSIZE;k++)
  379.         first[k] = buf[k];
  380.       }
  381.       else/*-如果不是要最后分配的一块--*/
  382.       {
  383.        for(k=0;k<DISKSIZE;k++)
  384.         first[k] =buf[k];
  385.       }
  386.       fat[item].item = i;  /*--找到一块后将它的序号存放在上一块的指针中-*/
  387.       fat[i].em_disk = '1'/*--置找到的磁盘快的空闲标志位为已分配-*/
  388.       fat[i].item = -1;  /*--它的指针为 -1 (即没有下一块)-*/
  389.    }
  390.    /*--修改文件打开表用户的长度-*/
  391.    u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len;
  392.    /*--修改目录项的文件长度-*/
  393.    cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;
  394.  }
  395.  return 0;
  396. }
  397. /*----------------------------------------------------------------------------------------------*/
  398. /*----------------------------------------读文件------------------------------------------------*/
  399. int read(int fd, char *buf)
  400. {
  401.  int len = u_opentable.openitem[fd].size;
  402.  char *first;
  403.  int i, j, item;
  404.  int ilen1, modlen;
  405.  item = u_opentable.openitem[fd].firstdisk;
  406.  if(len>u_opentable.openitem[fd].size) /*--欲读出的文件长度比实际文件长度长-*/
  407.   return(-1);
  408.  ilen1 = len/DISKSIZE;
  409.  modlen = len%DISKSIZE;
  410.  if(modlen!=0)
  411.   ilen1 = ilen1+1; /*--计算文件所占磁盘的块数-*/
  412.  first = fdisk+item*DISKSIZE; /*--计算文件的起始位置-*/
  413.  for(i=0;i<ilen1;i++)
  414.  {
  415.   if(i==ilen1-1) /*--如果在最后一个磁盘块-*/
  416.   {
  417.    for(j=0;j<len-i*DISKSIZE;j++)
  418.     buf[i*DISKSIZE+j] = first[j];
  419.   }
  420.   else /*--不在最后一块磁盘块-*/
  421.   {
  422.    for(j=0;j<len-i*DISKSIZE;j++)
  423.     buf[i*DISKSIZE+j] = first[j];
  424.    item = fat[item].item; /*-查找下一盘块-*/
  425.    first = fdisk+item*DISKSIZE;
  426.   }
  427.  }
  428.  return 0;
  429. }
  430. /*----------------------------------------------------------------------------------------------*/
  431. /*----------------------------------------删除文件----------------------------------------------*/
  432. int del(char *name)
  433. {
  434.  int i,cur_item,item,temp;
  435.  for(i=2;i<MSD+2;i++) /*--查找要删除文件是否在当前目录中-*/
  436.  {
  437.   if(!strcmp(cur_dir->directitem[i].name,name))
  438.    break;
  439.  }
  440.  cur_item = i; /*--用来保存目录项的序号,供释放目录中-*/
  441.     if(i>=MSD+2) /*--如果不在当前目录中-*/
  442.             return(-1);
  443.  if(cur_dir->directitem[cur_item].property!='0'/*--如果删除的(不)是目录-*/
  444.    return(-3);
  445.  for(i=0;i<MOFN;i++) /*--如果文件打开,则不能删除,退出-*/
  446.  {
  447.        if(!strcmp(u_opentable.openitem[i].name,name))
  448.                      return(-2);
  449.  }
  450.  item = cur_dir->directitem[cur_item].firstdisk;/*--该文件的起始盘块号-*/
  451.  while(item!=-1) /*--释放空间,将FAT表对应项进行修改-*/
  452.  {
  453.   temp = fat[item].item;
  454.   fat[item].item = -1;
  455.   fat[item].em_disk = '0';
  456.   item = temp;
  457.  }
  458.  /*-----------------释放目录项-----------------------*/
  459.  cur_dir->directitem[cur_item].sign = 0;
  460.  cur_dir->directitem[cur_item].firstdisk = -1;
  461.  strcpy(u_opentable.openitem[cur_item].name,"");
  462.     cur_dir->directitem[cur_item].next = -1;
  463.     cur_dir->directitem[cur_item].property = '0';
  464.  cur_dir->directitem[cur_item].size = 0;
  465.  return 0;
  466. }
  467. /*----------------------------------------------------------------------------------------------*/
  468. /*---------------------------------------创建子目录---------------------------------------------*/
  469. int mkdir(char *name)
  470. {
  471.  int i,j;
  472.  struct direct *cur_mkdir;
  473.  if(strchr(name,'//'))/*如果目录名中有 '/'字符*/
  474.   return(-4);
  475.  if(!strcmp(name,"."))
  476.   return(-6);
  477.  if(!strcmp(name,".."))
  478.   return(-6);
  479.  if(strlen(name)>8)  /*-如果目录名长度大于 8位-*/
  480.   return(-1);
  481.  for(i=2;i<MSD+2;i++) /*-如果有空闲目录项退出-*/
  482.  {
  483.   if(cur_dir->directitem[i].firstdisk==-1)
  484.    break;
  485.  }
  486.  if(i>=MSD+2) /*-目录/文件 已满-*/
  487.   return(-2);
  488.  for(j=2;j<MSD+2;j++) /*-判断是否有重名-*/
  489.  {
  490.   if(!strcmp(cur_dir->directitem[j].name,name))
  491.    break;
  492.  }
  493.  if(j<MSD+2)  /*-如果有重名-*/
  494.   return(-3);
  495.  for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*-找到空闲磁盘块 j 后退出-*/ 
  496.  {
  497.   if(fat[j].em_disk=='0')
  498.    break;
  499.  }
  500.  if(j>=DISK_NUM)
  501.   return(-5);
  502.  fat[j].em_disk='1'/*-将该空闲块设置为已分配-*/
  503.  /*-------------填写目录项----------*/
  504.   strcpy(cur_dir->directitem[i].name,name);
  505.   cur_dir->directitem[i].firstdisk=j;
  506.   cur_dir->directitem[i].size=ROOT_DISK_SIZE;
  507.   cur_dir->directitem[i].next=j;  /*-指向子目录(其实就是其本身)的起始盘块号-*/
  508.   cur_dir->directitem[i].property='1';
  509.   /*-sign=1为根标志,这里可以省略-*/
  510.   /*-所创目录在虚拟磁盘上的地址(内存物理地址)-*/
  511.   cur_mkdir=(struct direct *)(fdisk+cur_dir->directitem[i].firstdisk*DISKSIZE);
  512.   /*-初始化目录-*/
  513.   /*-指向当前目录的目录项-*/
  514.   cur_mkdir->directitem[0].sign=0;
  515.   cur_mkdir->directitem[0].firstdisk=cur_dir->directitem[i].firstdisk;
  516.   strcpy(cur_mkdir->directitem[0].name,".");
  517.   cur_mkdir->directitem[0].next=cur_mkdir->directitem[0].firstdisk;
  518.   cur_mkdir->directitem[0].property='1';
  519.   cur_mkdir->directitem[0].size=ROOT_DISK_SIZE;
  520.   /*-指向上一级目录的目录项-*/
  521.   cur_mkdir->directitem[1].sign=cur_dir->directitem[0].sign;/*-指向上一级目录的目录项-*/
  522.   cur_mkdir->directitem[1].firstdisk=cur_dir->directitem[0].firstdisk;
  523.   strcpy(cur_mkdir->directitem[1].name,"..");
  524.   cur_mkdir->directitem[1].next=cur_mkdir->directitem[1].firstdisk;
  525.   cur_mkdir->directitem[1].property='1';
  526.   cur_mkdir->directitem[1].size=ROOT_DISK_SIZE;
  527.   for(i=2;i<MSD+2;i++) /*-子目录都初始化为空-*/
  528.   {
  529.    cur_mkdir->directitem[i].sign=0;
  530.    cur_mkdir->directitem[i].firstdisk=-1;
  531.    strcpy(cur_mkdir->directitem[i].name,"");
  532.    cur_mkdir->directitem[i].next=-1;
  533.    cur_mkdir->directitem[i].property='0';
  534.    cur_mkdir->directitem[i].size=0;
  535.   }
  536.   return 0;
  537. }
  538. /*----------------------------------------------------------------------------------------------*/
  539. /*---------------------------------------删除子目录---------------------------------------------*/
  540. int rmdir(char *name)
  541. {
  542.  int i,j,item;
  543.  struct direct *temp_dir;
  544.  /*-检查当前目录项中有无该目录-*/
  545.  for(i=2;i<MSD+2;i++)
  546.  {
  547.   if(!strcmp(cur_dir->directitem[i].name,name))
  548.    break;
  549.  }
  550.  if(cur_dir->directitem[i].property!='1')/*-删除的不是目录-*/
  551.   return(-3);
  552.  if(i>=MSD+2) /*-没有这个文件或目录-*/
  553.   return(-1);
  554.  /*-判断要删除的目录有无子目录-*/
  555.  /*-要删除的目录起始地址-*/
  556.  temp_dir=(struct direct *)(fdisk+cur_dir->directitem[i].next*DISKSIZE);
  557.  for(j=2;j<MSD+2;j++)
  558.  {
  559.   if(temp_dir->directitem[j].next!=-1)
  560.    break;
  561.  }
  562.  if(j<MSD+2)  /*-有子目录或文件-*/
  563.   return(-2); /*-有关联则报错,也可以采取级联删除,像Windows-*/
  564.  /*------------找到起始盘块号,并将其释放----------------*/
  565.  item=cur_dir->directitem[i].firstdisk;
  566.  fat[item].em_disk='0';
  567.  /*-修改目录项-*/
  568.  cur_dir->directitem[i].sign=0;
  569.  cur_dir->directitem[i].firstdisk=-1;
  570.  strcpy(cur_dir->directitem[i].name,"");
  571.  cur_dir->directitem[i].next=-1;
  572.  cur_dir->directitem[i].property='0';
  573.  cur_dir->directitem[i].size=0;
  574.   
  575.   return 0;
  576. }
  577. /*----------------------------------------------------------------------------------------------*/
  578. /*-------------------------------显示当前目录的子目录-------------------------------------------*/
  579. void dir()
  580. {
  581.  int i;
  582.  for(i=0;i<MSD+2;i++)
  583.  {
  584.   if(cur_dir->directitem[i].firstdisk!=-1) /*-如果存在子目录-*/
  585.   {           /*-其本身和父目录也算?-*/
  586.    printf("%s/t",cur_dir->directitem[i].name);
  587.    if(cur_dir->directitem[i].property=='0'/*-文件-*/
  588.     printf("%d/t/t/n",cur_dir->directitem[i].size);
  589.    else          /*-目录-*/
  590.     printf("/t<DIR>/t/n");
  591.   }
  592.  }
  593. }
  594. /*----------------------------------------------------------------------------------------------*/
  595. /*---------------------------------------更改当前目录-------------------------------------------*/
  596. int cd(char *name)
  597. {
  598.  int i,j,item;
  599.  char *str,*str1;
  600.  char *temp,*point,*point1;
  601.  struct direct *temp_dir;
  602.  temp_dir=cur_dir;  /*-先用临时目录代替当前目录-*/
  603.  str=name;  /*-str用来记录下次查找的起始地址-*/
  604.  if(!strcmp("//",name)) /*如果输入"/" ,回根目录*/
  605.  {
  606.   cur_dir = root;
  607.   strcpy(bufferdir,"Root:");
  608.   return 0;
  609.  }
  610.  j=0;
  611.  for(i=0;i<(int)strlen(str);i++)/*查找有两个连续是"/",即"//",退出 */ 
  612.  {
  613.   if(name[i]=='//')
  614.   {
  615.    j++;
  616.    if(j>=2)
  617.    {
  618.     return -3;
  619.    }
  620.   }
  621.   else
  622.    j=0;
  623.  }
  624.  if(name[0]=='//'/*如果最后一个是"/" ,去掉这个"/"*/
  625.  {
  626.   temp_dir = root;
  627.   strcpy(bufferdir,"Root:");
  628.   str++;
  629.  }
  630.  if(str[strlen(str)-1] == '//')
  631.  {
  632.   str[strlen(str)-1] = '/0';
  633.  }
  634.  str1=strchr(str,'//'); /*-找到'/'字符的位置-*/
  635.  temp = (char *)malloc(DIR_LENGTH*sizeof(char));/*-为子目录的名字分配空间-*/
  636.  while(str1!=NULL) /*-找到-*/
  637.  {
  638.   
  639.   for(i=0;i<str1-str;i++)
  640.   {
  641.    temp[i]=str[i];
  642.   }
  643.   temp[i]='/0';
  644.   for(j=2;j<MSD+2;j++) /*-查找该子目录是否在当前目录中-*/ 
  645.   {
  646.    if(!strcmp(temp_dir->directitem[j].name,temp))
  647.     break;
  648.   }
  649.   if(j>=MSD+2) /*-不在当前目录-*/
  650.    return(-1);
  651.   item=temp_dir->directitem[j].firstdisk;
  652.   temp_dir=(struct direct *)(fdisk+item*DISKSIZE); /*-计算当前目录物理位置-*/
  653.   str=str1+1;
  654.   str1=strchr(str,'//');
  655.   //free(temp);
  656.  }
  657.  str1=str1+strlen(str);
  658.  for(i=0;i<(int)strlen(str);i++)
  659.   temp[i]=str[i];
  660.  temp[i]='/0';
  661.  for(j=0;j<MSD+2;j++) /*-查找该子目录是否在当前目录中-*/
  662.  {
  663.   if(!strcmp(temp_dir->directitem[j].name,temp))
  664.    break;
  665.  }
  666.  free(temp);/*释放申请的临时空间*/
  667.  if(temp_dir->directitem[j].property!='1'/*-打开的不是目录-*/ 
  668.   return(-2);
  669.  if(j>=MSD+2)  /*-不在当前目录-*/
  670.   return(-1); 
  671.  item=temp_dir->directitem[j].firstdisk;
  672.  /*-当前目录在磁盘中位置-*/
  673.  temp_dir=(struct direct *)(fdisk+item*DISKSIZE);
  674.  if(!strcmp("..",name))
  675.  {
  676.   if(cur_dir->directitem[j-1].sign!=1) /*-如果子目录不是根目录-*/
  677.   {
  678.    point=strchr(bufferdir,'//');
  679.    while(point!=NULL)
  680.    {
  681.     point1=point+1; /*-减去'/'所占的空间,记录下次查找的起始地址-*/
  682.     point=strchr(point1,'//');
  683.    }
  684.    *(point1-1)='/0'/*-将上一级目录删除-*/
  685.   }
  686.   else
  687.   {
  688.   }
  689.  }
  690.  else if(!strcmp(".",name))
  691.  {
  692.   bufferdir=bufferdir; /*-如果是当前目录则不变-*/
  693.  }
  694.  else
  695.  {
  696.   if(name[0] !='//')
  697.   bufferdir = strcat(bufferdir,"//"); /*-修改当前目录-*/
  698.   bufferdir = strcat(bufferdir,name);
  699.  }
  700.  cur_dir=temp_dir;  /*-将当前目录确定下来-*/
  701.  return 0;
  702. }
  703. /*----------------------------------------------------------------------------------------------*/
  704. /*---------------------------------------显示当前路径-------------------------------------------*/
  705. void show()
  706. {
  707.  printf("%s>",bufferdir);
  708. }
  709. /*----------------------------------------------------------------------------------------------*/
  710. /*--------------------------------------输出提示信息--------------------------------------------*/
  711. void print()
  712. {
  713.  printf("********************************************************************************/n");
  714.  printf("/t/t/tWelcome to DOS File system!/n");
  715.  printf("--------------------------------------------------------------------------------/n");
  716.  printf("/t/t 退出文件系统  halt/n");
  717.  printf("/t/t 创建文件  create 文件名/n");
  718.  printf("/t/t 删除文件  del 文件名/n");
  719.  printf("/t/t 打开文件  open 文件名/n");
  720.  printf("/t/t 关闭文件  close 文件名/n");
  721.  printf("/t/t 写文件   write/n");
  722.  printf("/t/t 读文件   read/n/n");
  723.  printf("/t/t 创建子目录  mkdir 目录名/n");
  724.  printf("/t/t 删除子目录  rmdir 目录名/n");
  725.  printf("/t/t 显示当前目录的子目录 dir/n");
  726.  printf("/t/t 更改当前目录  cd 目录名/n");
  727.  printf("--------------------------------------------------------------------------------/n");
  728. }
  729. /*----------------------------------------------------------------------------------------------*/
  730. /*------------------------------------------主函数----------------------------------------------*/
  731. void main()
  732. {
  733.  FILE *fp;
  734.  char ch;
  735.  char a[100];
  736.  char code[11][10];
  737.  char name[10];
  738.  int i,flag,r_size;
  739.  char *contect;
  740.  contect = (char *)malloc(MAX_WRITE*sizeof(char));
  741.  if((fp=fopen("disk.dat","rb"))==NULL)/*如果还没有进行格式化,则要格式化*/
  742.  {
  743.   printf("You have not format,Do you want format?(y/n)");
  744.   scanf("%c",&ch);
  745.   if(ch=='y')
  746.   {
  747.    initfile();
  748.    printf("Successfully format! /n");
  749.   }
  750.   else 
  751.   {
  752.    return;
  753.   }
  754.  }
  755.   
  756.  enter();
  757.  print();
  758.  show();
  759.  /*将命令全部保存在CODE数组中*/
  760.  strcpy(code[0],"halt");
  761.  strcpy(code[1],"create");
  762.  strcpy(code[2],"open");
  763.  strcpy(code[3],"close");
  764.  strcpy(code[4],"write");
  765.  strcpy(code[5],"read");
  766.  strcpy(code[6],"del");
  767.  strcpy(code[7],"mkdir");
  768.  strcpy(code[8],"rmdir");
  769.  strcpy(code[9],"dir");
  770.  strcpy(code[10],"cd");
  771.  while(1)
  772.  {
  773.   scanf("%s",a);
  774.   for(i=0;i<11;i++)
  775.   {
  776.    if(!strcmp(code[i],a))
  777.     break;
  778.   }
  779.   switch(i)
  780.   {
  781.    case 0: //*--退出文件系统--//
  782.     free(contect);
  783.     halt();
  784.     return;
  785.    case 1: //*--创建文件--//
  786.     scanf("%s",name);
  787.     flag = create(name);
  788.     if(flag==-1)
  789.     {
  790.      printf("Error: /n The length is too long !/n");
  791.     }
  792.     else if(flag==-2)
  793.     {
  794.      printf("Error: /n The direct item is already full !/n");
  795.     }
  796.     else if(flag==-3)
  797.     {
  798.      printf("Error: /n The number of openfile is too much !/n");
  799.     }
  800.     else if(flag==-4)
  801.     {
  802.      printf("Error: /n The name is already in the direct !/n");
  803.     }
  804.     else if(flag==-5)
  805.     {
  806.      printf("Error: /n The disk space is full!/n");
  807.     }
  808.     else
  809.     {
  810.      printf("Successfully create a file! /n");
  811.     }
  812.     show();
  813.     break;
  814.    case 2://--打开文件--//
  815.     scanf("%s",name);
  816.     fd = open(name);
  817.     if(fd == -1)
  818.     {
  819.      printf("Error: /n The open file not exit! /n");
  820.     }
  821.     else if(fd == -2)
  822.     {
  823.      printf("Error: /n The file have already opened! /n");
  824.     }
  825.     else if(fd == -3)
  826.     {
  827.      printf("Error: /n The number of open file is too much! /n");
  828.     }
  829.     else if(fd == -4)
  830.     {
  831.      printf("Error: /n It is a direct,can not open for read or write! /n");
  832.     }
  833.     else
  834.     {
  835.      printf("Successfully opened! /n");
  836.     }
  837.     show();
  838.     break;
  839.    case 3://--关闭文件--//
  840.     scanf("%s",name);
  841.     flag = close(name);
  842.     if(flag == -1)
  843.     {
  844.      printf("Error:/n The file is not opened ! /n");
  845.     }
  846.     else 
  847.     {
  848.      printf("Successfully closed! /n");
  849.     }
  850.     show();
  851.     break;
  852.   
  853.    case 4:/*--写文件--*/
  854.     if(fd ==-1)
  855.     {
  856.      printf("Error:/n The file is not opened ! /n");
  857.     }
  858.     else
  859.     {
  860.      printf("Please input the file contect:");
  861.      scanf("%s",contect);
  862.      flag=write(fd,contect,strlen(contect));
  863.      if(flag == 0)
  864.      {
  865.       printf("Successfully write! /n");
  866.      }
  867.      else
  868.      {
  869.       printf("Error:/n The disk size is not enough! /n");
  870.      }
  871.     }
  872.     show();
  873.     break;
  874.    case 5:/*--读文件--*/
  875.     if(fd ==-1)
  876.     {
  877.      printf("Error:/n The file is not opened ! /n");
  878.     }
  879.     else
  880.     {
  881.      flag = read(fd,contect);
  882.      if(flag == -1)
  883.      { 
  884.       printf("Error: /n The size is over the length of the file! /n");
  885.      }
  886.      else
  887.      {
  888.       //printf("Successfully read! /n The contect is :");
  889.       for(i=0;i<u_opentable.openitem[fd].size;i++)
  890.       {
  891.        printf("%c",contect[i]);
  892.       }
  893.       printf("/t/n");
  894.      }
  895.     }
  896.     show();
  897.     break;
  898.    case 6://*--删除文件--
  899.     scanf("%s",name);
  900.     flag = del(name);
  901.     if(flag == -1)
  902.     {
  903.      printf("Error:/n The file not exit! /n");
  904.     }
  905.     else if(flag == -2)
  906.     {
  907.      printf("Error:/n The file is opened,please first close it ! /n");
  908.     }
  909.     else if(flag == -3)
  910.     {
  911.      printf("Error:/n The delete is not file ! /n");
  912.     }
  913.     else
  914.     {
  915.      printf("Successfully delete! /n");
  916.     }
  917.     show();
  918.     break;
  919.    
  920.    case 7://*--创建子目录--/
  921.     scanf("%s",name);
  922.     flag = mkdir(name);
  923.     if(flag == -1)
  924.     {
  925.      printf("Error:/n The length of name is to long! /n");
  926.     }
  927.     else if(flag == -2)
  928.     {
  929.      printf("Error:/n The direct item is already full ! /n");
  930.     }
  931.     else if(flag == -3)
  932.     {
  933.      printf("Error:/n The name is already in the direct ! /n");
  934.     }
  935.     else if(flag == -4)
  936.     {
  937.      printf("Error:/n // can not in the name of a direct ! /n");
  938.     }
  939.     else if(flag == -5)
  940.     {
  941.      printf("Error: /n The disk space is full!/n");
  942.     }
  943.     else if(flag == -6)
  944.     {
  945.      printf("Error: /n '..' or '.' can not as the name of the direct!/n");
  946.     }
  947.     else if(flag == 0)
  948.     {
  949.      printf("Successfully make dircet! /n");
  950.     }
  951.     show();
  952.     break;
  953.    case 8://*--删除子目录--/
  954.     scanf("%s",name);
  955.     flag = rmdir(name);
  956.     if(flag == -1)
  957.     {
  958.      printf("Error:/n The direct is not exist! /n");
  959.     }
  960.     else if(flag == -2)
  961.     {
  962.      printf("Error:/nThe direct has son direct ,please first remove the son dircct!/n");
  963.     }
  964.     else if(flag == -3)
  965.     {
  966.      printf("Error:/n The remove is not direct ! /n");
  967.     }
  968.     else if(flag == 0)
  969.     {
  970.      printf("Successfully remove dircet! /n");
  971.     }
  972.     show();
  973.     break;
  974.    case 9://*--显示当前子目录--/
  975.     dir();
  976.     show();
  977.     break;
  978.    case 10:/*--更改当前目录--*/
  979.     scanf("%s",name);
  980.     flag = cd(name);
  981.     if(flag == -1)
  982.     {
  983.      printf("Error:/n The path no correct!/n");
  984.     }
  985.     else if(flag == -2)
  986.     {
  987.      printf("Error:/nThe opened is not direct!/n");
  988.     }
  989.     else if(flag == -3)
  990.     {
  991.      printf("Error:/nThe '//' is too much !/n"); 
  992.     }
  993.     show();
  994.     break;
  995.    
  996.    default:
  997.     printf("/n Error!/n The command is wrong! /n");
  998.     show();
  999.   }
  1000.  }
  1001. }
 

你可能感兴趣的:(File,null,存储,FP,disk,磁盘)