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

📄 文件系统实现.c

📁 用vc写得操作系统课程设计题
💻 C
📖 第 1 页 / 共 3 页
字号:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define DIR_LENGTH  1024     /*路径最长可达100字节*/
#define MAX_WRITE 1024*128    /*写入文字可达128k字节*/      
#define MEM_D_SIZE 1024*1024    /*1M磁盘空间*/
#define DISKSIZE 1024     /*磁盘快的大小 1K*/
#define MSD   5      /*最大子目录数 5 (类似五叉树)*/
#define DISK_NUM MEM_D_SIZE/DISKSIZE  /*磁盘快数目 1024=1M/1K*/
#define FATSIZE  DISK_NUM*sizeof(struct fatitem) /*FAT表大小 8K=8192B (理想应该是 1.5K)*/
#define MOFN  5      /*最大文件打开数 5 (即除根以外最大深度为5)*/
#define ROOT_DISK_NO FATSIZE/DISKSIZE+1  /*根目录起始盘快号 9*/
#define ROOT_DISK_SIZE sizeof(struct direct)/*根目录大小 196*/ 

/*---------------FAT表项结构-----------------------*/

struct fatitem  /* size 8*/
{
 int item;  /*存放文件下一个磁盘的指针*/
 char em_disk; /*磁盘块是否空闲标志位 0 空闲*/
};

/*-------------------目录项结构------------------------*/
struct direct  /* size 196*/
{
 /*-----文件控制快信息-----*/
 struct FCB
 {
   char name[9];  /*文件/目录名 8位*/
   char property;  /*属性 1位目录 0位普通文件*/
   int size;   /*文件/目录字节数(原注释位盘块数)*/
   int firstdisk;  /*文件/目录 起始盘块号*/
   int next;   /*子目录起始盘块号*/
   int sign;   /*1是根目录 0不是根目录*/

 }directitem[MSD+2];
 
};

/*------------------文件打开表项结构--------------------------*/
struct opentable   /* size 104*/
{
 struct openttableitem /* size 20*/
 {
  char name[9]; /*文件名*/
  int firstdisk; /*起始盘块号*/ 
  int size;  /*文件的大小*/
 }openitem[MOFN];
 int cur_size;  /*当前打文件的数目*/
};

/*-------------------------------------------------------------------*/
struct fatitem *fat;   /*FAT表*/
struct direct *root;   /*根目录*/
struct direct *cur_dir;   /*当前目录*/
struct opentable u_opentable; /*文件打开表*/
int  fd=-1;     /*文件打开表的序号*/
char *bufferdir;    /*记录当前路径的名称*/
char *fdisk;     /*虚拟磁盘起始地址*/

void initfile();
void   format();
void enter();
void     halt();
int create(char *name);
int   open(char *name);
int  close(char *name);
int write(int fd,char *buf,int len);
int  read(int fd,char *buf);
int   del(char *name);
int mkdir(char *name);
int rmdir(char *name);
void dir();
int cd(char *name);
void print();
void show();

/*----------------------------------------------------------------------------------------------*/
/*------------------------------------------初始化文件系统--------------------------------------*/
void initfile()
{
 fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/
 format();
 free(fdisk);
}

/*----------------------------------------------------------------------------------------------*/
/*------------------------------------------格式化----------------------------------------------*/
void format()
{
 int i;
 FILE *fp;

 fat = (struct fatitem *)(fdisk+DISKSIZE); /*计算FAT表地址(为什么向后偏移 1k)*/
 /*-----初始化FAT表------------*/
 fat[0].item=-1;  /*引导块*/
 fat[0].em_disk='1';

 for(i=1;i<ROOT_DISK_NO-1;i++) /*存放 FAT表的磁盘块号*/
 {
  fat[i].item=i+1;
  fat[i].em_disk='1';  
 }

 fat[ROOT_DISK_NO-1].item=-1;
 fat[ROOT_DISK_NO-1].em_disk='1';
 fat[ROOT_DISK_NO].item=-1;  /*存放根目录的磁盘块号*/
 fat[ROOT_DISK_NO].em_disk='1';
 
 for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)
 {
  fat[i].item = -1;
  fat[i].em_disk = '0';  
 }
 /*-----------------------------------------------*/
 root = (struct direct *)(fdisk+DISKSIZE+FATSIZE); /*根目录的地址*/
 /*初始化目录*/
 /*---------指向当前目录的目录项---------*/
 root->directitem[0].sign = 1;
 root->directitem[0].firstdisk = ROOT_DISK_NO;
 strcpy(root->directitem[0].name,".");
 root->directitem[0].next = root->directitem[0].firstdisk;
 root->directitem[0].property = '1';
 root->directitem[0].size = ROOT_DISK_SIZE;
 /*-------指向上一级目录的目录项---------*/
 root->directitem[1].sign = 1;
 root->directitem[1].firstdisk = ROOT_DISK_NO;
 strcpy(root->directitem[1].name,"..");
 root->directitem[1].next = root->directitem[0].firstdisk;
 root->directitem[1].property = '1';
 root->directitem[1].size = ROOT_DISK_SIZE;

 for(i=2;i<MSD+2;i++) /*-子目录初始化为空-*/
 {
  root->directitem[i].sign = 0;
  root->directitem[i].firstdisk = -1;
  strcpy(root->directitem[i].name,"");
  root->directitem[i].next = -1;
  root->directitem[i].property = '0';
  root->directitem[i].size = 0;  
 }
 /*-------测试写入文件的数据---------
 for(i=0;i<DISK_NUM;i++)
 {
  printf("%d,%d\n",fat[i].item,fat[i].em_disk);
 }

 for(i=0;i<MSD+2;i++)
 {
  printf("%d,%s,%d,%c,%d,%d\n",root->directitem[i].firstdisk,
   root->directitem[i].name,root->directitem[i].next,
   root->directitem[i].property,root->directitem[i].sign,
   root->directitem[i].size);
 }

 for(i=0;i<DISK_NUM;i++)
 { 
  fread(&fat[i],sizeof(struct fatitem),1,fp);
  printf("%d,%d\n",fat[i].em_disk,fat[i].item);
 }

 for(i=0;i<MSD+2;i++)
 {
  fread(&root->directitem[i],sizeof(struct FCB),1,fp);
  printf("%d,%s,%d,%c,%d,%d\n",root->directitem[i].firstdisk,
   root->directitem[i].name,root->directitem[i].next,
   root->directitem[i].property,root->directitem[i].sign,
   root->directitem[i].size);
 }

 ------test end-----*/
 if((fp = fopen("disk.dat","wb"))==NULL)
 {
  printf("Error:\n Cannot open file \n");
  return;
 }
 if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1) /*把虚拟磁盘空间保存到磁盘文件中*/  
 {
  printf("Error:\n File write error! \n");
 }

 fclose(fp);

}
/*----------------------------------------------------------------------------------------------*/
/*--------------------------------进入文件系统--------------------------------------------------*/
void enter()
{
     FILE *fp;
     int i;

     fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/
     if((fp=fopen("disk.dat","rb"))==NULL)
     {
          printf("Error:\nCannot open file\n");
          return;                                
     }
     if(!fread(fdisk,MEM_D_SIZE,1,fp))  /*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/    
  {
          printf("Error:\nCannot read file\n");
          exit(0);  
  }
     fat = (struct fatitem *)(fdisk+DISKSIZE);  /*找到FAT表地址*/
     root = (struct direct *)(fdisk+DISKSIZE+FATSIZE);/*找到根目录地址*/
     fclose(fp);
     /*--------------初始化用户打开表------------------*/
     for(i=0;i<MOFN;i++)
     {
          strcpy(u_opentable.openitem[i].name,"");
          u_opentable.openitem[i].firstdisk = -1;
          u_opentable.openitem[i].size = 0;              
     }
     u_opentable.cur_size = 0;
     
     cur_dir = root; /*当前目录为根目录*/
     bufferdir = (char *)malloc(DIR_LENGTH*sizeof(char));
     strcpy(bufferdir,"Root:"); /*显示根目录为E:*/ 
}


/*----------------------------------------------------------------------------------------------*/
/*------------------------------------退出文件系统----------------------------------------------*/
void halt()
{
     FILE *fp;
     int i;

     if((fp=fopen("disk.dat","wb"))==NULL)
     {
          printf("Error:\nCannot open file\n");
          return;                                
     }
     if(!fwrite(fdisk,MEM_D_SIZE,1,fp)) /*把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */
  {
  printf("Error:\nFile write error!\n");
  }
     fclose(fp);
     
     free(fdisk);
  free(bufferdir);
     
     for(i=0;i<MOFN;i++) /*撤销用户打开表 (好像没有必要,系统自动会回收)*/
     {
          strcpy(u_opentable.openitem[i].name,"");
          u_opentable.openitem[i].firstdisk = 0;
          u_opentable.openitem[i].size = 0;              
     }
     u_opentable.cur_size = 0; /*用户打开文件数清零*/
     
     return;
     
}


/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------创建文件----------------------------------------------*/
int create(char *name)
{
 
    int i,j;
        
    if(strlen(name)>8) /*文件名大于 8位*/
           return(-1);
           
    for(i=2;i<MSD+2;i++) /*找到第一个空闲子目录*/
    {
           if(cur_dir->directitem[i].firstdisk==-1)
                     break;             
    }
    
    for(j=2;j<MSD+2;j++) /*检查创建文件是否与已存在的文件重名*/
    {
           if(!strcmp(cur_dir->directitem[j].name,name))
                     break;   
    }
    
    if(i>=MSD+2) /*无空目录项*/
            return(-2);
    if(u_opentable.cur_size>=MOFN) /*打开文件太多(第五层)*/
            return(-3); 
    if(j<MSD+2)     /*文件已经存在*/
            return(-4);
            
    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 = 0;
    cur_dir->directitem[i].next = j;
    cur_dir->directitem[i].property = '0';
 /*cur_dir->directitem[i].sign  丢失*/
    /*---------------------------------*/
    fd = open(name); /*打开所创建的文件*/
    return 0;
 
}


/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------打开文件----------------------------------------------*/
int open(char *name)
{
    int i, j;
       
    for(i=2;i<MSD+2;i++) /*文件是否存在*/
    {
           if(!strcmp(cur_dir->directitem[i].name,name))
                     break;   
    }
    
    if(i>=MSD+2) /*文件不存在*/
            return(-1);
 /*--------是文件还是目录-----------------------*/  
 if(cur_dir->directitem[i].property=='1')/*是目录,不可打开读写*/
   return(-4);

    /*--------文件是否打开-----------------------*/        
    for(j=0;j<MOFN;j++)
    {
           if(!strcmp(u_opentable.openitem[j].name,name))
      break;
    } 
     if(j<MOFN)  /*文件已经打开*/
            return(-2);
            
                   
    if(u_opentable.cur_size>=MOFN) /*文件打开太多*/
            return(-3); 

    /*--------查找一个空闲用户打开表项-----------------------*/    
    for(j=0;j<MOFN;j++)
    {
           if(u_opentable.openitem[j].firstdisk==-1)
                     break;    
    }
    /*--------------填写表项的相关信息------------------------*/
    u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk;
    strcpy(u_opentable.openitem[j].name,name);
    u_opentable.openitem[j].size = cur_dir->directitem[i].size;
    u_opentable.cur_size++;
    /*----------返回用户打开表表项的序号--------------------------*/
    return(j);
}


/*----------------------------------------------------------------------------------------------*/
/*----------------------------------------关闭文件----------------------------------------------*/
int close(char *name)
{
    int i;

    for(i=0;i<MOFN;i++)
    {
           if(!strcmp(u_opentable.openitem[i].name,name))
                     break;   
    } 
    if(i>=MOFN)  /*--文件没有打开-*/  
            return(-1); 
    /*-----------清空该文件的用户打开表项的内容---------------------*/
    strcpy(u_opentable.openitem[i].name,"");
    u_opentable.openitem[i].firstdisk = -1;
    u_opentable.openitem[i].size = 0;
    u_opentable.cur_size--;
    
    fd = -1; /*文件打开表的序号为 -1 */
    return 0;
}


/*----------------------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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