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

📄 文件系统实现.c

📁 用vc写得操作系统课程设计题
💻 C
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------写文件------------------------------------------------*/
int write(int fd, char *buf, int len)
{
 char *first;
 int item, i, j, k;
 int ilen1, ilen2, modlen, temp;
 /*----------用 $ 字符作为空格 # 字符作为换行符-----------------------*/
 char Space = 32; /*SPACE的ASCII码值*/
 char Endter= '\n';
 
 for(i=0;i<len;i++)
 {
  if(buf[i] == '$') /*用 $ 字符作为空格*/
   buf[i] = Space;
  else if(buf[i] == '#')
   buf[i] = Endter;
 }

 /*----------读取用户打开表对应表项第一个盘块号-----------------------*/

 item = u_opentable.openitem[fd].firstdisk;

 /*-------------找到当前目录所对应表项的序号-------------------------*/
 for(i=2;i<MSD+2;i++)
 {
   if(cur_dir->directitem[i].firstdisk==item)
      break;
 }
 temp = i; /*-存放当前目录项的下标-*/
 /*------找到的item 是该文件的最后一块磁盘块-------------------*/
 while(fat[item].item!=-1) 
 {
  item =fat[item].item; /*-查找该文件的下一盘块--*/
 }

 /*-----计算除该文件的最末地址-------*/
 first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE;
 
 /*-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------*/
 if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len)
 {
   strcpy(first,buf);
   u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len;
   cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;
 }
 else
 {
   for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++)
   {/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/ 
    first[i] = buf [i];
   }
   /*-----计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储-------*/
   ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);
   ilen2 = ilen1/DISKSIZE;  
   modlen = ilen1%DISKSIZE;
   if(modlen>0)
      ilen2 = ilen2+1; /*--还需要多少块磁盘块-*/
 /*调试时特别注意*/
   for(j=0;j<ilen2;j++)
   {
      for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)/*寻找空闲磁盘块*/
      {
       if(fat[i].em_disk=='0')
         break;
      }
      if(i>=DISK_NUM) /*--如果磁盘块已经分配完了-*/
       return(-1);
      first = fdisk+i*DISKSIZE; /*--找到的那块空闲磁盘块的起始地址-*/
      if(j==ilen2-1) /*--如果是最后要分配的一块-*/
      {
       for(k=0;k<len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)-j*DISKSIZE;k++)
        first[k] = buf[k];
      }
      else/*-如果不是要最后分配的一块--*/
      {
       for(k=0;k<DISKSIZE;k++)
        first[k] =buf[k];
      }

      fat[item].item = i;  /*--找到一块后将它的序号存放在上一块的指针中-*/
      fat[i].em_disk = '1'; /*--置找到的磁盘快的空闲标志位为已分配-*/
      fat[i].item = -1;  /*--它的指针为 -1 (即没有下一块)-*/
   }
   /*--修改文件打开表用户的长度-*/
   u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len;
   /*--修改目录项的文件长度-*/
   cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;
 }
 return 0;
}


/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------读文件------------------------------------------------*/
int read(int fd, char *buf)
{
 int len = u_opentable.openitem[fd].size;
 char *first;
 int i, j, item;
 int ilen1, modlen;

 item = u_opentable.openitem[fd].firstdisk;
 if(len>u_opentable.openitem[fd].size) /*--欲读出的文件长度比实际文件长度长-*/
  return(-1);

 ilen1 = len/DISKSIZE;
 modlen = len%DISKSIZE;
 if(modlen!=0)
  ilen1 = ilen1+1; /*--计算文件所占磁盘的块数-*/

 first = fdisk+item*DISKSIZE; /*--计算文件的起始位置-*/

 for(i=0;i<ilen1;i++)
 {
  if(i==ilen1-1) /*--如果在最后一个磁盘块-*/
  {
   for(j=0;j<len-i*DISKSIZE;j++)
    buf[i*DISKSIZE+j] = first[j];
  }
  else /*--不在最后一块磁盘块-*/
  {
   for(j=0;j<len-i*DISKSIZE;j++)
    buf[i*DISKSIZE+j] = first[j];
   item = fat[item].item; /*-查找下一盘块-*/
   first = fdisk+item*DISKSIZE;
  }
 }
 return 0;
}


/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------删除文件----------------------------------------------*/
int del(char *name)
{
 int i,cur_item,item,temp;

 for(i=2;i<MSD+2;i++) /*--查找要删除文件是否在当前目录中-*/
 {
  if(!strcmp(cur_dir->directitem[i].name,name))
   break;
 }
 cur_item = i; /*--用来保存目录项的序号,供释放目录中-*/

    if(i>=MSD+2) /*--如果不在当前目录中-*/
            return(-1);

 if(cur_dir->directitem[cur_item].property!='0') /*--如果删除的(不)是目录-*/
   return(-3);

 for(i=0;i<MOFN;i++) /*--如果文件打开,则不能删除,退出-*/
 {
       if(!strcmp(u_opentable.openitem[i].name,name))
                     return(-2);
 }
 item = cur_dir->directitem[cur_item].firstdisk;/*--该文件的起始盘块号-*/
 while(item!=-1) /*--释放空间,将FAT表对应项进行修改-*/
 {
  temp = fat[item].item;
  fat[item].item = -1;
  fat[item].em_disk = '0';
  item = temp;
 }
 /*-----------------释放目录项-----------------------*/
 cur_dir->directitem[cur_item].sign = 0;
 cur_dir->directitem[cur_item].firstdisk = -1;
 strcpy(u_opentable.openitem[cur_item].name,"");
    cur_dir->directitem[cur_item].next = -1;
    cur_dir->directitem[cur_item].property = '0';
 cur_dir->directitem[cur_item].size = 0;

 return 0;
}

/*----------------------------------------------------------------------------------------------*/
/*---------------------------------------创建子目录---------------------------------------------*/
int mkdir(char *name)
{
 int i,j;
 struct direct *cur_mkdir;

 if(strchr(name,'\\'))/*如果目录名中有 '\'字符*/
  return(-4);
 if(!strcmp(name,"."))
  return(-6);
 if(!strcmp(name,".."))
  return(-6);
 if(strlen(name)>8)  /*-如果目录名长度大于 8位-*/
  return(-1);

 for(i=2;i<MSD+2;i++) /*-如果有空闲目录项退出-*/
 {
  if(cur_dir->directitem[i].firstdisk==-1)
   break;
 }
 if(i>=MSD+2) /*-目录/文件 已满-*/
  return(-2);
 for(j=2;j<MSD+2;j++) /*-判断是否有重名-*/
 {
  if(!strcmp(cur_dir->directitem[j].name,name))
   break;
 }
 if(j<MSD+2)  /*-如果有重名-*/
  return(-3);
 for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*-找到空闲磁盘块 j 后退出-*/ 
 {
  if(fat[j].em_disk=='0')
   break;
 }
 if(j>=DISK_NUM)
  return(-5);
 fat[j].em_disk='1'; /*-将该空闲块设置为已分配-*/

 /*-------------填写目录项----------*/
  strcpy(cur_dir->directitem[i].name,name);
  cur_dir->directitem[i].firstdisk=j;
  cur_dir->directitem[i].size=ROOT_DISK_SIZE;
  cur_dir->directitem[i].next=j;  /*-指向子目录(其实就是其本身)的起始盘块号-*/
  cur_dir->directitem[i].property='1';
  /*-sign=1为根标志,这里可以省略-*/

  /*-所创目录在虚拟磁盘上的地址(内存物理地址)-*/
  cur_mkdir=(struct direct *)(fdisk+cur_dir->directitem[i].firstdisk*DISKSIZE);

  /*-初始化目录-*/
  /*-指向当前目录的目录项-*/
  cur_mkdir->directitem[0].sign=0;
  cur_mkdir->directitem[0].firstdisk=cur_dir->directitem[i].firstdisk;
  strcpy(cur_mkdir->directitem[0].name,".");
  cur_mkdir->directitem[0].next=cur_mkdir->directitem[0].firstdisk;
  cur_mkdir->directitem[0].property='1';
  cur_mkdir->directitem[0].size=ROOT_DISK_SIZE;

  /*-指向上一级目录的目录项-*/
  cur_mkdir->directitem[1].sign=cur_dir->directitem[0].sign;/*-指向上一级目录的目录项-*/
  cur_mkdir->directitem[1].firstdisk=cur_dir->directitem[0].firstdisk;
  strcpy(cur_mkdir->directitem[1].name,"..");
  cur_mkdir->directitem[1].next=cur_mkdir->directitem[1].firstdisk;
  cur_mkdir->directitem[1].property='1';
  cur_mkdir->directitem[1].size=ROOT_DISK_SIZE;

  for(i=2;i<MSD+2;i++) /*-子目录都初始化为空-*/
  {
   cur_mkdir->directitem[i].sign=0;
   cur_mkdir->directitem[i].firstdisk=-1;
   strcpy(cur_mkdir->directitem[i].name,"");
   cur_mkdir->directitem[i].next=-1;
   cur_mkdir->directitem[i].property='0';
   cur_mkdir->directitem[i].size=0;
  }
  return 0;
}

/*----------------------------------------------------------------------------------------------*/
/*---------------------------------------删除子目录---------------------------------------------*/
int rmdir(char *name)
{
 int i,j,item;
 struct direct *temp_dir;
 /*-检查当前目录项中有无该目录-*/
 for(i=2;i<MSD+2;i++)
 {
  if(!strcmp(cur_dir->directitem[i].name,name))
   break;
 }
 if(cur_dir->directitem[i].property!='1')/*-删除的不是目录-*/
  return(-3);
 if(i>=MSD+2) /*-没有这个文件或目录-*/
  return(-1);
 /*-判断要删除的目录有无子目录-*/
 /*-要删除的目录起始地址-*/
 temp_dir=(struct direct *)(fdisk+cur_dir->directitem[i].next*DISKSIZE);
 for(j=2;j<MSD+2;j++)
 {
  if(temp_dir->directitem[j].next!=-1)
   break;
 }
 if(j<MSD+2)  /*-有子目录或文件-*/
  return(-2); /*-有关联则报错,也可以采取级联删除,像Windows-*/
 /*------------找到起始盘块号,并将其释放----------------*/
 item=cur_dir->directitem[i].firstdisk;
 fat[item].em_disk='0';
 /*-修改目录项-*/
 cur_dir->directitem[i].sign=0;
 cur_dir->directitem[i].firstdisk=-1;
 strcpy(cur_dir->directitem[i].name,"");
 cur_dir->directitem[i].next=-1;
 cur_dir->directitem[i].property='0';
 cur_dir->directitem[i].size=0;
  
  return 0;
}

/*----------------------------------------------------------------------------------------------*/
/*-------------------------------显示当前目录的子目录-------------------------------------------*/
void dir()
{
 int i;
 for(i=0;i<MSD+2;i++)
 {
  if(cur_dir->directitem[i].firstdisk!=-1) /*-如果存在子目录-*/
  {           /*-其本身和父目录也算?-*/
   printf("%s\t",cur_dir->directitem[i].name);
   if(cur_dir->directitem[i].property=='0') /*-文件-*/
    printf("%d\t\t\n",cur_dir->directitem[i].size);
   else          /*-目录-*/
    printf("\t<DIR>\t\n");
  }
 }
}

/*----------------------------------------------------------------------------------------------*/
/*---------------------------------------更改当前目录-------------------------------------------*/

int cd(char *name)
{
 int i,j,item;
 char *str,*str1;
 char *temp,*point,*point1;
 struct direct *temp_dir;
 temp_dir=cur_dir;  /*-先用临时目录代替当前目录-*/
 str=name;  /*-str用来记录下次查找的起始地址-*/

 if(!strcmp("\\",name)) /*如果输入"\" ,回根目录*/
 {
  cur_dir = root;
  strcpy(bufferdir,"Root:");
  return 0;
 }
 j=0;
 for(i=0;i<(int)strlen(str);i++)/*查找有两个连续是"\",即"\\",退出 */ 
 {
  if(name[i]=='\\')
  {
   j++;
   if(j>=2)
   {
    return -3;
   }
  }
  else
   j=0;
 }

 if(name[0]=='\\') /*如果最后一个是"\" ,去掉这个"\"*/
 {
  temp_dir = root;
  strcpy(bufferdir,"Root:");
  str++;
 }
 if(str[strlen(str)-1] == '\\')
 {
  str[strlen(str)-1] = '\0';
 }


 str1=strchr(str,'\\'); /*-找到'\'字符的位置-*/

 temp = (char *)malloc(DIR_LENGTH*sizeof(char));/*-为子目录的名字分配空间-*/
 while(str1!=NULL) /*-找到-*/
 {
  
  for(i=0;i<str1-str;i++)
  {
   temp[i]=str[i];
  }
  temp[i]='\0';

  for(j=2;j<MSD+2;j++) /*-查找该子目录是否在当前目录中-*/ 
  {
   if(!strcmp(temp_dir->directitem[j].name,temp))
    break;
  }
  if(j>=MSD+2) /*-不在当前目录-*/
   return(-1);
  item=temp_dir->directitem[j].firstdisk;
  temp_dir=(struct direct *)(fdisk+item*DISKSIZE); /*-计算当前目录物理位置-*/
  str=str1+1;

⌨️ 快捷键说明

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