【操作系统】C语言编写的FAT16文件系统

【操作系统】C语言编写的FAT16文件系统

 

这是操作系统的期末课程设计作业之一,主要功能是在物理内存中虚拟出一个1M大小的FAT16的文件系统,然后把它读入内存中,进行具体的文件操作,具体的实用性不大,主要目的是为了练习C语言,帮助理解文件系统的特点,代码如下:

 

  1. #include <stdio.h>  
  2. #include <malloc.h>  
  3. #include <string.h>  
  4. #include <time.h>  
  5.   
  6. #define BLOCKSIZE 1024  // 磁盘块大小  
  7. #define SIZE 1024000  // 虚拟磁盘空间大小  
  8. #define END 65535  // FAT中的文件结束标志  
  9. #define FREE 0  // FAT中盘块空闲标志  
  10. #define ROOTBLOCKNUM 2  // 根目录区所占盘块数  
  11. #define MAXOPENFILE 10  // 最多同时打开文件个数t  
  12. #define MAXTEXT 10000  
  13.   
  14. /* 文件控制块 */  
  15. typedef struct FCB  
  16. {  
  17.     char filename[8];  // 文件名  
  18.     char exname[3];  // 文件扩展名  
  19.     unsigned char attribute;  // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件  
  20.     unsigned short time;  // 文件创建时间  
  21.     unsigned short date;  // 文件创建日期  
  22.     unsigned short first;  // 文件起始盘块号  
  23.     unsigned long length;  // 文件长度  
  24.     char free;  // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配  
  25. }fcb;  
  26.   
  27. /* 文件分配表 */  
  28. typedef struct FAT  
  29. {  
  30.     unsigned short id;  // 磁盘块的状态(空闲的,最后的,下一个)  
  31. }fat;  
  32. /* 用户打开文件表 */  
  33. typedef struct USEROPEN  
  34. {  
  35.     char filename[8];  // 文件名  
  36.     char exname[3];  // 文件扩展名  
  37.     unsigned char attribute;  // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件  
  38.     unsigned short time;  // 文件创建时间  
  39.     unsigned short date;  // 文件创建日期  
  40.     unsigned short first;  // 文件起始盘块号  
  41.     unsigned long length;  // 文件长度(对数据文件是字节数,对目录文件可以是目录项个数)  
  42.     char free;  // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配  
  43.   
  44.     unsigned short dirno;  // 相应打开文件的目录项在父目录文件中的盘块号  
  45.     int diroff;  // 相应打开文件的目录项在父目录文件的dirno盘块中的目录项序号  
  46.     char dir[80];  // 相应打开文件所在的目录名,这样方便快速检查出指定文件是否已经打开  
  47.     int father;  // 父目录在打开文件表项的位置  
  48.     int count;  // 读写指针在文件中的位置,文件的总字符数  
  49.     char fcbstate;  // 是否修改了文件的FCB的内容,如果修改了置为1,否则为0  
  50.     char topenfile;  // 表示该用户打开表项是否为空,若值为0,表示为空,否则表示已被某打开文件占据  
  51. }useropen;  
  52.   
  53. /* 引导块 */  
  54. typedef struct BLOCK0  
  55. {  
  56.     char magic[10];  // 文件系统魔数  
  57.     char information[200];  // 存储一些描述信息,如磁盘块大小、磁盘块数量、最多打开文件数等  
  58.     unsigned short root;  // 根目录文件的起始盘块号  
  59.     unsigned char *startblock;  // 虚拟磁盘上数据区开始位置  
  60. }block0;  
  61. unsigned char *myvhard;  // 指向虚拟磁盘的起始地址  
  62. useropen openfilelist[MAXOPENFILE];  // 用户打开文件表数组  
  63. int curdir;  // 用户打开文件表中的当前目录所在打开文件表项的位置  
  64. char currentdir[80];  // 记录当前目录的目录名(包括目录的路径)  
  65. unsigned char* startp;  // 记录虚拟磁盘上数据区开始位置  
  66. char myfilename[] = "myfilesys";//文件系统的文件名  
  67.   
  68. void startsys();  // 进入文件系统  
  69. void my_format();  // 磁盘格式化  
  70. void my_cd(char *dirname);  // 更改当前目录  
  71. void my_mkdir(char *dirname);  // 创建子目录  
  72. void my_rmdir(char *dirname);  // 删除子目录  
  73. void my_ls();  // 显示目录  
  74. void my_create (char *filename);  // 创建文件  
  75. void my_rm(char *filename);  // 删除文件  
  76. int my_open(char *filename);  // 打开文件  
  77. int my_close(int fd);  // 关闭文件  
  78. int my_write(int fd);  // 写文件  
  79. int do_write(int fd, char *text, int len, char wstyle);  // 实际写文件  
  80. int my_read (int fd, int len);  // 读文件  
  81. int do_read (int fd, int len,char *text);  // 实际读文件  
  82. void my_exitsys();  // 退出文件系统  
  83. unsigned short findblock();  // 寻找空闲盘块  
  84. int findopenfile();  // 寻找空闲文件表项  
  85. void startsys()  
  86. {  
  87.     FILE *fp;  
  88.     unsigned char buf[SIZE];  
  89.     fcb *root;  
  90.     int i;  
  91.     myvhard = (unsigned char *)malloc(SIZE);//申请虚拟磁盘空间  
  92.     memset(myvhard, 0, SIZE);//将myvhard中前SIZE个字节用 0 替换并返回 myvhard  
  93.     if((fp = fopen(myfilename, "r")) != NULL)  
  94.     {  
  95.         fread(buf, SIZE, 1, fp);//将二进制文件读取到缓冲区  
  96.         fclose(fp);//关闭打开的文件,缓冲区数据写入文件,释放系统提供文件资源  
  97.         if(strcmp(((block0 *)buf)->magic, "10101010"))//判断开始的8个字节内容是否为文件系统魔数  
  98.         {  
  99.             printf("myfilesys is not exist,begin to creat the file...\n");  
  100.             my_format();  
  101.         }  
  102.         else  
  103.         {  
  104.             for(i = 0; i < SIZE; i++)  
  105.                 myvhard[i] = buf[i];  
  106.         }  
  107.     }  
  108.     else  
  109.     {  
  110.         printf("myfilesys is not exist,begin to creat the file...\n");  
  111.         my_format();  
  112.     }  
  113.     root = (fcb *)(myvhard + 5 * BLOCKSIZE);  
  114.     strcpy(openfilelist[0].filename, root->filename);  
  115.     strcpy(openfilelist[0].exname, root->exname);  
  116.     openfilelist[0].attribute = root->attribute;  
  117.     openfilelist[0].time = root->time;  
  118.     openfilelist[0].date = root->date;  
  119.     openfilelist[0].first = root->first;  
  120.     openfilelist[0].length = root->length;  
  121.     openfilelist[0].free = root->free;  
  122.     openfilelist[0].dirno = 5;  
  123.     openfilelist[0].diroff = 0;  
  124.     strcpy(openfilelist[0].dir, "\\root\\");  
  125.     openfilelist[0].father = 0;  
  126.     openfilelist[0].count = 0;  
  127.     openfilelist[0].fcbstate = 0;  
  128.     openfilelist[0].topenfile = 1;  
  129.     for(i = 1; i < MAXOPENFILE; i++)  
  130.         openfilelist[i].topenfile = 0;  
  131.     curdir = 0;  
  132.     strcpy(currentdir, "\\root\\");  
  133.     startp = ((block0 *)myvhard)->startblock;  
  134. }  
  135. void my_format()  
  136. {  
  137.     FILE *fp;  
  138.     fat *fat1, *fat2;  
  139.     block0 *blk0;  
  140.     time_t now;  
  141.     struct tm *nowtime;  
  142.     fcb *root;  
  143.     int i;  
  144.     blk0 = (block0 *)myvhard;  
  145.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  146.     fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);  
  147.     root = (fcb *)(myvhard + 5 * BLOCKSIZE);  
  148.     strcpy(blk0->magic, "10101010");  
  149.     strcpy(blk0->information, "My FileSystem Ver 1.0 \n Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2\n");  
  150.     blk0->root = 5;  
  151.     blk0->startblock = (unsigned char *)root;  
  152.     for(i = 0; i < 5; i++)  
  153.     {  
  154.         fat1->id = END;  
  155.         fat2->id = END;  
  156.         fat1++;  
  157.         fat2++;  
  158.     }  
  159.     fat1->id = 6;  
  160.     fat2->id = 6;  
  161.     fat1++;  
  162.     fat2++;  
  163.     fat1->id = END;  
  164.     fat2->id = END;  
  165.     fat1++;  
  166.     fat2++;  
  167.     for(i = 7; i < SIZE / BLOCKSIZE; i++)  
  168.     {  
  169.         fat1->id = FREE;  
  170.         fat2->id = FREE;  
  171.         fat1++;  
  172.         fat2++;  
  173.     }  
  174.     now = time(NULL);  
  175.     nowtime = localtime(&now);  
  176.     strcpy(root->filename, ".");  
  177.     strcpy(root->exname, "");  
  178.     root->attribute = 0x28;  
  179.     root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;  
  180.     root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;  
  181.     root->first = 5;  
  182.     root->length = 2 * sizeof(fcb);  
  183.     root->free = 1;  
  184.     root++;  
  185.     now = time(NULL);  
  186.     nowtime = localtime(&now);  
  187.     strcpy(root->filename, "..");  
  188.     strcpy(root->exname, "");  
  189.     root->attribute = 0x28;  
  190.     root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;  
  191.     root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;  
  192.     root->first = 5;  
  193.     root->length = 2 * sizeof(fcb);  
  194.     root->free = 1;  
  195.     fp = fopen(myfilename, "w");  
  196.     fwrite(myvhard, SIZE, 1, fp);  
  197.     fclose(fp);  
  198. }  
  199. void my_cd(char *dirname)  
  200. {  
  201.     char *dir;  
  202.     int fd;  
  203.     dir = strtok(dirname, "\\");//分解字符串为一组字符串。dirname为要分解的字符串,"\\"为分隔符字符串  
  204.     if(strcmp(dir, ".") == 0)  
  205.         return;  
  206.     else if(strcmp(dir, "..") == 0)  
  207.     {  
  208.         if(curdir)  
  209.             curdir = my_close(curdir);  
  210.         return;  
  211.     }  
  212.     else if(strcmp(dir, "root") == 0)  
  213.     {  
  214.         while(curdir)  
  215.             curdir = my_close(curdir);  
  216.         dir = strtok(NULL, "\\");  
  217.     }  
  218.     while(dir)  
  219.     {  
  220.         fd = my_open(dir);  
  221.         if(fd != -1)  
  222.             curdir = fd;  
  223.         else  
  224.             return;  
  225.         dir = strtok(NULL, "\\");  
  226.     }  
  227. }  
  228. void my_mkdir(char *dirname)  
  229. {  
  230.     fcb *fcbptr;  
  231.     fat *fat1, *fat2;  
  232.     time_t now;  
  233.     struct tm *nowtime;  
  234.     char text[MAXTEXT];  
  235.     unsigned short blkno;  
  236.     int rbn, fd, i;  
  237.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  238.     fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);  
  239.     openfilelist[curdir].count = 0;  
  240.     rbn = do_read(curdir, openfilelist[curdir].length, text);  
  241.     fcbptr = (fcb *)text;  
  242.     for(i = 0; i < rbn / sizeof(fcb); i++)//在当前目录下找,是否有重名目录  
  243.     {  
  244.         if(strcmp(fcbptr->filename, dirname) == 0 && strcmp(fcbptr->exname, "") == 0)  
  245.         {  
  246.             printf("Error,the dirname is already exist!\n");  
  247.             return;  
  248.         }  
  249.         fcbptr++;  
  250.     }  
  251.     fcbptr = (fcb *)text;  
  252.     for(i = 0; i < rbn / sizeof(fcb); i++)  
  253.     {  
  254.         if(fcbptr->free == 0)  
  255.             break;  
  256.         fcbptr++;  
  257.     }  
  258.     blkno = findblock();//寻找空闲盘块  
  259.     if(blkno == -1)  
  260.         return;  
  261.     (fat1 + blkno)->id = END;  
  262.     (fat2 + blkno)->id = END;  
  263.     now = time(NULL);  
  264.     nowtime = localtime(&now);  
  265.     strcpy(fcbptr->filename, dirname);  
  266.     strcpy(fcbptr->exname, "");  
  267.     fcbptr->attribute = 0x30;  
  268.     fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;  
  269.     fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;  
  270.     fcbptr->first = blkno;  
  271.     fcbptr->length = 2 * sizeof(fcb);  
  272.     fcbptr->free = 1;  
  273.     openfilelist[curdir].count = i * sizeof(fcb);  
  274.     do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);  
  275.   
  276.     fd = my_open(dirname);//建立新目录的'.','..'目录  
  277.     if(fd == -1)  
  278.         return;  
  279.     fcbptr = (fcb *)malloc(sizeof(fcb));  
  280.     now = time(NULL);  
  281.     nowtime = localtime(&now);  
  282.     strcpy(fcbptr->filename, ".");  
  283.     strcpy(fcbptr->exname, "");  
  284.     fcbptr->attribute = 0x28;  
  285.     fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;  
  286.     fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;  
  287.     fcbptr->first = blkno;  
  288.     fcbptr->length = 2 * sizeof(fcb);  
  289.     fcbptr->free = 1;  
  290.     do_write(fd, (char *)fcbptr, sizeof(fcb), 2);  
  291.     now = time(NULL);  
  292.     nowtime = localtime(&now);  
  293.     strcpy(fcbptr->filename, "..");  
  294.     strcpy(fcbptr->exname, "");  
  295.     fcbptr->attribute = 0x28;  
  296.     fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;  
  297.     fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;  
  298.     fcbptr->first = blkno;  
  299.     fcbptr->length = 2 * sizeof(fcb);  
  300.     fcbptr->free = 1;  
  301.     do_write(fd, (char *)fcbptr, sizeof(fcb), 2);  
  302.     free(fcbptr);  
  303.     my_close(fd);  
  304.   
  305.     fcbptr = (fcb *)text;  
  306.     fcbptr->length = openfilelist[curdir].length;  
  307.     openfilelist[curdir].count = 0;  
  308.     do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);  
  309.     openfilelist[curdir].fcbstate = 1;  
  310. }  
  311.   
  312. void my_rmdir(char *dirname)  
  313. {  
  314.     fcb *fcbptr,*fcbptr2;  
  315.     fat *fat1, *fat2, *fatptr1, *fatptr2;  
  316.     char text[MAXTEXT], text2[MAXTEXT];  
  317.     unsigned short blkno;  
  318.     int rbn, rbn2, fd, i, j;  
  319.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  320.     fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);  
  321.     if(strcmp(dirname, ".") == 0 || strcmp(dirname, "..") == 0)  
  322.     {  
  323.         printf("Error,can't remove this directory.\n");  
  324.         return;  
  325.     }  
  326.     openfilelist[curdir].count = 0;  
  327.     rbn = do_read(curdir, openfilelist[curdir].length, text);  
  328.     fcbptr = (fcb *)text;  
  329.     for(i = 0; i < rbn / sizeof(fcb); i++)//查找要删除的目录  
  330.     {  
  331.         if(strcmp(fcbptr->filename, dirname) == 0 && strcmp(fcbptr->exname, "") == 0)  
  332.             break;  
  333.         fcbptr++;  
  334.     }  
  335.     if(i == rbn / sizeof(fcb))  
  336.     {  
  337.         printf("Error,the directory is not exist.\n");  
  338.         return;  
  339.     }  
  340.     fd = my_open(dirname);  
  341.     rbn2 = do_read(fd, openfilelist[fd].length, text2);  
  342.     fcbptr2 = (fcb *)text2;  
  343.     for(j = 0; j < rbn2 / sizeof(fcb); j++)//判断要删除目录是否为空  
  344.     {  
  345.         if(strcmp(fcbptr2->filename, ".") && strcmp(fcbptr2->filename, "..") && strcmp(fcbptr2->filename, ""))  
  346.         {  
  347.             my_close(fd);  
  348.             printf("Error,the directory is not empty.\n");  
  349.             return;  
  350.         }  
  351.         fcbptr2++;  
  352.     }  
  353.     blkno = openfilelist[fd].first;  
  354.     while(blkno != END)  
  355.     {  
  356.         fatptr1 = fat1 + blkno;  
  357.         fatptr2 = fat2 + blkno;  
  358.         blkno = fatptr1->id;  
  359.         fatptr1->id = FREE;  
  360.         fatptr2->id = FREE;  
  361.     }  
  362.     my_close(fd);  
  363.     strcpy(fcbptr->filename, "");  
  364.     fcbptr->free = 0;  
  365.     openfilelist[curdir].count = i * sizeof(fcb);  
  366.     do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);  
  367.     openfilelist[curdir].fcbstate = 1;  
  368. }  
  369. void my_ls()  
  370. {  
  371.     fcb *fcbptr;  
  372.     char text[MAXTEXT];  
  373.     int rbn, i;  
  374.     openfilelist[curdir].count = 0;  
  375.     rbn = do_read(curdir, openfilelist[curdir].length, text);  
  376.     fcbptr = (fcb *)text;  
  377.     for(i = 0; i < rbn / sizeof(fcb); i++)  
  378.     {  
  379.         if(fcbptr->free)  
  380.         {  
  381.             if(fcbptr->attribute & 0x20)  
  382.                 printf("%s\\\t\t<DIR>\t\t%d/%d/%d\t%02d:%02d:%02d\n", fcbptr->filename, (fcbptr->date >> 9) + 1980, (fcbptr->date >> 5) & 0x000f, fcbptr->date & 0x001f, fcbptr->time >> 11, (fcbptr->time >> 5) & 0x003f, fcbptr->time & 0x001f * 2);  
  383.             else  
  384.                 printf("%s.%s\t\t%dB\t\t%d/%d/%d\t%02d:%02d:%02d\t\n", fcbptr->filename, fcbptr->exname, (int)(fcbptr->length), (fcbptr->date >> 9) + 1980, (fcbptr->date >> 5) & 0x000f, fcbptr->date & 0x1f, fcbptr->time >> 11, (fcbptr->time >> 5) & 0x3f, fcbptr->time & 0x1f * 2);  
  385.         }  
  386.         fcbptr++;  
  387.     }  
  388. }  
  389. void my_create(char *filename)  
  390. {  
  391.     fcb *fcbptr;  
  392.     fat *fat1, *fat2;  
  393.     char *fname, *exname, text[MAXTEXT];  
  394.     unsigned short blkno;  
  395.     int rbn, i;  
  396.     time_t now;  
  397.     struct tm *nowtime;  
  398.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  399.     fat2 = (fat *)(myvhard + BLOCKSIZE);  
  400.     fname = strtok(filename, ".");  
  401.     exname = strtok(NULL, ".");  
  402.     if(strcmp(fname, "") == 0)  
  403.     {  
  404.         printf("Error,creating file must have a right name.\n");  
  405.         return;  
  406.     }  
  407.     if(!exname)  
  408.     {  
  409.         printf("Error,creating file must have a extern name.\n");  
  410.         return;  
  411.     }  
  412.     openfilelist[curdir].count = 0;  
  413.     rbn = do_read(curdir, openfilelist[curdir].length, text);  
  414.     fcbptr = (fcb *)text;  
  415.     for(i = 0; i < rbn / sizeof(fcb); i++)  
  416.     {  
  417.         if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)  
  418.         {  
  419.             printf("Error,the filename is already exist!\n");  
  420.             return;  
  421.         }  
  422.         fcbptr++;  
  423.     }  
  424.     fcbptr = (fcb *)text;  
  425.     for(i = 0; i < rbn / sizeof(fcb); i++)  
  426.     {  
  427.         if(fcbptr->free == 0)  
  428.             break;  
  429.         fcbptr++;  
  430.     }  
  431.     blkno = findblock();  
  432.     if(blkno == -1)  
  433.         return;  
  434.     (fat1 + blkno)->id = END;  
  435.     (fat2 + blkno)->id = END;  
  436.   
  437.     now = time(NULL);  
  438.     nowtime = localtime(&now);  
  439.     strcpy(fcbptr->filename, fname);  
  440.     strcpy(fcbptr->exname, exname);  
  441.     fcbptr->attribute = 0x00;  
  442.     fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;  
  443.     fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;  
  444.     fcbptr->first = blkno;  
  445.     fcbptr->length = 0;  
  446.     fcbptr->free = 1;  
  447.     openfilelist[curdir].count = i * sizeof(fcb);  
  448.     do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);  
  449.     fcbptr = (fcb *)text;  
  450.     fcbptr->length = openfilelist[curdir].length;  
  451.     openfilelist[curdir].count = 0;  
  452.     do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);  
  453.     openfilelist[curdir].fcbstate = 1;  
  454. }  
  455. void my_rm(char *filename)  
  456. {  
  457.     fcb *fcbptr;  
  458.     fat *fat1, *fat2, *fatptr1, *fatptr2;  
  459.     char *fname, *exname, text[MAXTEXT];  
  460.     unsigned short blkno;  
  461.     int rbn, i;  
  462.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  463.     fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);  
  464.     fname = strtok(filename, ".");  
  465.     exname = strtok(NULL, ".");  
  466.     if(strcmp(fname, "") == 0)  
  467.     {  
  468.         printf("Error,removing file must have a right name.\n");  
  469.         return;  
  470.     }  
  471.     if(!exname)  
  472.     {  
  473.         printf("Error,removing file must have a extern name.\n");  
  474.         return;  
  475.     }  
  476.     openfilelist[curdir].count = 0;  
  477.     rbn = do_read(curdir, openfilelist[curdir].length, text);  
  478.     fcbptr = (fcb *)text;  
  479.     for(i = 0; i < rbn / sizeof(fcb); i++)  
  480.     {  
  481.         if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)  
  482.             break;  
  483.         fcbptr++;  
  484.     }  
  485.     if(i == rbn / sizeof(fcb))  
  486.     {  
  487.         printf("Error,the file is not exist.\n");  
  488.         return;  
  489.     }  
  490.     openfilelist[curdir].count = 0;  
  491.     rbn = do_read(curdir, openfilelist[curdir].length, text);  
  492.     fcbptr = (fcb *)text;  
  493.     for(i = 0; i < rbn / sizeof(fcb); i++)  
  494.     {  
  495.         if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)  
  496.             break;  
  497.         fcbptr++;  
  498.     }  
  499.     if(i == rbn / sizeof(fcb))  
  500.     {  
  501.         printf("Error,the file is not exist.\n");  
  502.         return;  
  503.     }  
  504.     blkno = fcbptr->first;  
  505.     while(blkno != END)  
  506.     {  
  507.         fatptr1 = fat1 + blkno;  
  508.         fatptr2 = fat2 + blkno;  
  509.         blkno = fatptr1->id;  
  510.         fatptr1->id = FREE;  
  511.         fatptr2->id = FREE;  
  512.     }  
  513.     strcpy(fcbptr->filename, "");  
  514.     fcbptr->free = 0;  
  515.     openfilelist[curdir].count = i * sizeof(fcb);  
  516.     do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);  
  517.     openfilelist[curdir].fcbstate = 1;  
  518. }  
  519. int my_open(char *filename)  
  520. {  
  521.     fcb *fcbptr;  
  522.     char *fname, exname[3], *str, text[MAXTEXT];  
  523.     int rbn, fd, i;  
  524.     fname = strtok(filename, ".");  
  525.     str = strtok(NULL, ".");  
  526.     if(str)  
  527.         strcpy(exname, str);  
  528.     else  
  529.         strcpy(exname, "");  
  530.     for(i = 0; i < MAXOPENFILE; i++)  
  531.     {  
  532.         if(strcmp(openfilelist[i].filename, fname) == 0 && strcmp(openfilelist[i].exname, exname) == 0 && i != curdir)  
  533.         {  
  534.             printf("Error,the file is already open.\n");  
  535.             return -1;  
  536.         }  
  537.     }  
  538.     openfilelist[curdir].count = 0;  
  539.     rbn = do_read(curdir, openfilelist[curdir].length, text);  
  540.     fcbptr = (fcb *)text;  
  541.     for(i = 0; i < rbn / sizeof(fcb); i++)  
  542.     {  
  543.         if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)  
  544.             break;  
  545.         fcbptr++;  
  546.     }  
  547.     if(i == rbn / sizeof(fcb))  
  548.     {  
  549.         printf("Error,the file is not exist.\n");  
  550.         return -1;  
  551.     }  
  552.     fd = findopenfile();  
  553.     if(fd == -1)  
  554.         return -1;  
  555.     strcpy(openfilelist[fd].filename, fcbptr->filename);  
  556.     strcpy(openfilelist[fd].exname, fcbptr->exname);  
  557.     openfilelist[fd].attribute = fcbptr->attribute;  
  558.     openfilelist[fd].time = fcbptr->time;  
  559.     openfilelist[fd].date = fcbptr->date;  
  560.     openfilelist[fd].first = fcbptr->first;  
  561.     openfilelist[fd].length = fcbptr->length;  
  562.     openfilelist[fd].free = fcbptr->free;  
  563.     openfilelist[fd].dirno = openfilelist[curdir].first;  
  564.     openfilelist[fd].diroff = i;  
  565.     strcpy(openfilelist[fd].dir, openfilelist[curdir].dir);  
  566.     strcat(openfilelist[fd].dir, filename);  
  567.     if(fcbptr->attribute & 0x20)  
  568.         strcat(openfilelist[fd].dir, "\\");  
  569.     openfilelist[fd].father = curdir;  
  570.     openfilelist[fd].count = 0;  
  571.     openfilelist[fd].fcbstate = 0;  
  572.     openfilelist[fd].topenfile = 1;  
  573.     return fd;  
  574. }  
  575. int my_close(int fd)  
  576. {  
  577.     fcb *fcbptr;  
  578.     int father;  
  579.     if(fd < 0 || fd >= MAXOPENFILE)  
  580.     {  
  581.         printf("Error,the file is not exist.\n");  
  582.         return -1;  
  583.     }  
  584.     if(openfilelist[fd].fcbstate)  
  585.     {  
  586.         fcbptr = (fcb *)malloc(sizeof(fcb));  
  587.         strcpy(fcbptr->filename, openfilelist[fd].filename);  
  588.         strcpy(fcbptr->exname, openfilelist[fd].exname);  
  589.         fcbptr->attribute = openfilelist[fd].attribute;  
  590.         fcbptr->time = openfilelist[fd].time;  
  591.         fcbptr->date = openfilelist[fd].date;  
  592.         fcbptr->first = openfilelist[fd].first;  
  593.         fcbptr->length = openfilelist[fd].length;  
  594.         fcbptr->free = openfilelist[fd].free;  
  595.         father = openfilelist[fd].father;  
  596.         openfilelist[father].count = openfilelist[fd].diroff * sizeof(fcb);  
  597.         do_write(father, (char *)fcbptr, sizeof(fcb), 2);  
  598.         free(fcbptr);  
  599.         openfilelist[fd].fcbstate = 0;  
  600.     }  
  601.     strcpy(openfilelist[fd].filename, "");  
  602.     strcpy(openfilelist[fd].exname, "");  
  603.     openfilelist[fd].topenfile = 0;  
  604.     return father;  
  605. }  
  606. int my_write(int fd)  
  607. {  
  608.     fat *fat1, *fat2, *fatptr1, *fatptr2;  
  609.     int wstyle, len, ll, tmp;  
  610.     char text[MAXTEXT];  
  611.     unsigned short blkno;  
  612.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  613.     fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);  
  614.     if(fd < 0 || fd >= MAXOPENFILE)  
  615.     {  
  616.         printf("The file is not exist!\n");  
  617.         return -1;  
  618.     }  
  619.     while(1)  
  620.     {  
  621.         printf("Please enter the number of write style:\n1.cut write\t2.cover write\t3.add write\n");  
  622.         scanf("%d", &wstyle);  
  623.         if(wstyle > 0 && wstyle < 4)  
  624.             break;  
  625.         printf("Input Error!");  
  626.     }  
  627.     getchar();  
  628.     switch(wstyle)  
  629.     {  
  630.         case 1:  
  631.             blkno = openfilelist[fd].first;  
  632.             fatptr1 = fat1 + blkno;  
  633.             fatptr2 = fat2 + blkno;  
  634.             blkno = fatptr1->id;  
  635.             fatptr1->id = END;  
  636.             fatptr2->id = END;  
  637.             while(blkno != END)  
  638.             {  
  639.                 fatptr1 = fat1 + blkno;  
  640.                 fatptr2 = fat2 + blkno;  
  641.                 blkno = fatptr1->id;  
  642.                 fatptr1->id = FREE;  
  643.                 fatptr2->id = FREE;  
  644.             }  
  645.             openfilelist[fd].count = 0;  
  646.             openfilelist[fd].length = 0;  
  647.             break;  
  648.         case 2:  
  649.             openfilelist[fd].count = 0;  
  650.             break;  
  651.         case 3:  
  652.             openfilelist[fd].count = openfilelist[fd].length;  
  653.             break;  
  654.         default:  
  655.             break;  
  656.     }  
  657.     ll = 0;  
  658.     printf("please input write data(end with Ctrl+Z):\n");  
  659.     while(gets(text))  
  660.     {  
  661.         len = strlen(text);  
  662.         text[len++] = '\n';  
  663.         text[len] = '\0';  
  664.         tmp = do_write(fd, text, len, wstyle);  
  665.         if(tmp != -1)  
  666.             ll += tmp;  
  667.         if(tmp < len)  
  668.         {  
  669.             printf("Wirte Error!");  
  670.             break;  
  671.         }  
  672.     }  
  673.     return ll;  
  674. }  
  675.   
  676. int do_write(int fd, char *text, int len, char wstyle)  
  677. {  
  678.     fat *fat1, *fat2, *fatptr1, *fatptr2;  
  679.     unsigned char *buf, *blkptr;  
  680.     unsigned short blkno, blkoff;  
  681.     int i, ll;  
  682.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  683.     fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);  
  684.     buf = (unsigned char *)malloc(BLOCKSIZE);  
  685.     if(buf == NULL)  
  686.     {  
  687.         printf("malloc failed!\n");  
  688.         return -1;  
  689.     }  
  690.     blkno = openfilelist[fd].first;  
  691.     blkoff = openfilelist[fd].count;  
  692.     fatptr1 = fat1 + blkno;  
  693.     fatptr2 = fat2 + blkno;  
  694.     while(blkoff >= BLOCKSIZE)  
  695.     {  
  696.         blkno = fatptr1->id;  
  697.         if(blkno == END)  
  698.         {  
  699.             blkno = findblock();  
  700.             if(blkno == -1)  
  701.             {  
  702.                 free(buf);  
  703.                 return -1;  
  704.             }  
  705.             fatptr1->id = blkno;  
  706.             fatptr2->id = blkno;  
  707.             fatptr1 = fat1 + blkno;  
  708.             fatptr2 = fat2 + blkno;  
  709.             fatptr1->id = END;  
  710.             fatptr2->id = END;  
  711.         }  
  712.         else  
  713.         {  
  714.             fatptr1 = fat1 + blkno;  
  715.             fatptr2 = fat2 + blkno;  
  716.         }  
  717.         blkoff = blkoff - BLOCKSIZE;  
  718.     }  
  719.   
  720.     ll = 0;  
  721.     while(ll < len)  
  722.     {  
  723.         blkptr = (unsigned char *)(myvhard + blkno * BLOCKSIZE);  
  724.         for(i = 0; i < BLOCKSIZE; i++)  
  725.             buf[i] = blkptr[i];  
  726.         for(;blkoff < BLOCKSIZE; blkoff++)  
  727.         {  
  728.             buf[blkoff] = text[ll++];  
  729.             openfilelist[fd].count++;  
  730.             if(ll == len)  
  731.                 break;  
  732.         }  
  733.         for(i = 0; i < BLOCKSIZE; i++)  
  734.             blkptr[i] = buf[i];  
  735.         if(ll < len)  
  736.         {  
  737.             blkno = fatptr1->id;  
  738.             if(blkno == END)  
  739.             {  
  740.                 blkno = findblock();  
  741.                 if(blkno == -1)  
  742.                     break;  
  743.                 fatptr1->id = blkno;  
  744.                 fatptr2->id = blkno;  
  745.                 fatptr1 = fat1 + blkno;  
  746.                 fatptr2 = fat2 + blkno;  
  747.                 fatptr1->id = END;  
  748.                 fatptr2->id = END;  
  749.             }  
  750.             else  
  751.             {  
  752.                 fatptr1 = fat1 + blkno;  
  753.                 fatptr2 = fat2 + blkno;  
  754.             }  
  755.             blkoff = 0;  
  756.             }  
  757.     }  
  758.     if(openfilelist[fd].count > openfilelist[fd].length)  
  759.         openfilelist[fd].length = openfilelist[fd].count;  
  760.     openfilelist[fd].fcbstate = 1;  
  761.     free(buf);  
  762.     return ll;  
  763. }  
  764. int my_read(int fd, int len)  
  765. {  
  766.     char text[MAXTEXT];  
  767.     int ll;  
  768.     if(fd < 0 || fd >= MAXOPENFILE)  
  769.     {  
  770.         printf("The File is not exist!\n");  
  771.         return -1;  
  772.     }  
  773.     openfilelist[fd].count = 0;  
  774.     ll = do_read(fd, len, text);  
  775.     if(ll != -1)  
  776.         printf("%s", text);  
  777.     else  
  778.         printf("Read Error!\n");  
  779.     return ll;  
  780. }  
  781. int do_read(int fd, int len, char *text)  
  782. {  
  783.     fat *fat1, *fatptr;  
  784.     unsigned char *buf, *blkptr;  
  785.     unsigned short blkno, blkoff;  
  786.     int i, ll;  
  787.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  788.     buf = (unsigned char *)malloc(BLOCKSIZE);  
  789.     if(buf == NULL)  
  790.     {  
  791.         printf("malloc failed!\n");  
  792.         return -1;  
  793.     }  
  794.     blkno = openfilelist[fd].first;  
  795.     blkoff = openfilelist[fd].count;  
  796.     if(blkoff >= openfilelist[fd].length)  
  797.     {  
  798.         puts("Read out of range!");  
  799.         free(buf);  
  800.         return -1;  
  801.     }  
  802.     fatptr = fat1 + blkno;  
  803.     while(blkoff >= BLOCKSIZE)  
  804.     {  
  805.         blkno = fatptr->id;  
  806.         blkoff = blkoff - BLOCKSIZE;  
  807.         fatptr = fat1 + blkno;  
  808.     }  
  809.     ll = 0;  
  810.     while(ll < len)  
  811.     {  
  812.         blkptr = (unsigned char *)(myvhard + blkno * BLOCKSIZE);  
  813.         for(i = 0; i < BLOCKSIZE; i++)  
  814.             buf[i] = blkptr[i];  
  815.         for(; blkoff < BLOCKSIZE; blkoff++)  
  816.         {  
  817.             text[ll++] = buf[blkoff];  
  818.             openfilelist[fd].count++;  
  819.             if(ll == len || openfilelist[fd].count == openfilelist[fd].length)  
  820.                 break;  
  821.         }  
  822.         if(ll < len && openfilelist[fd].count != openfilelist[fd].length)  
  823.         {  
  824.             blkno = fatptr->id;  
  825.             if(blkno == END)  
  826.                 break;  
  827.             blkoff = 0;  
  828.             fatptr = fat1 + blkno;  
  829.         }  
  830.     }  
  831.     text[ll] = '\0';  
  832.     free(buf);  
  833.     return ll;  
  834. }  
  835. void my_exitsys()  
  836. {  
  837.     FILE *fp;  
  838.     while(curdir)  
  839.         curdir = my_close(curdir);  
  840.     fp = fopen(myfilename, "w");  
  841.     fwrite(myvhard, SIZE, 1, fp);  
  842.     fclose(fp);  
  843.     free(myvhard);  
  844. }  
  845. unsigned short findblock()  
  846. {  
  847.     unsigned short i;  
  848.     fat *fat1, *fatptr;  
  849.     fat1 = (fat *)(myvhard + BLOCKSIZE);  
  850.     for(i = 7; i < SIZE / BLOCKSIZE; i++)  
  851.     {  
  852.         fatptr = fat1 + i;  
  853.         if(fatptr->id == FREE)  
  854.             return i;  
  855.     }  
  856.     printf("Error,Can't find free block!\n");  
  857.     return -1;  
  858. }  
  859.   
  860. int findopenfile()  
  861. {  
  862.     int i;  
  863.     for(i = 0; i < MAXTEXT; i++)  
  864.     {  
  865.         if(openfilelist[i].topenfile == 0)  
  866.             return i;  
  867.     }  
  868.     printf("Error,open too many files!\n");  
  869.     return -1;  
  870. }  
  871. int main()  
  872. {  
  873.     char cmd[15][10] = {"cd", "mkdir", "rmdir", "ls", "create", "rm", "open", "close", "write", "read", "exit"};  
  874.     char s[30], *sp;  
  875.     int cmdn, flag = 1, i;  
  876.     startsys();  
  877.     printf("*********************File System V1.0*******************************\n\n");  
  878.     printf("命令名\t\t命令参数\t\t命令说明\n\n");  
  879.     printf("cd\t\t目录名(路径名)\t\t切换当前目录到指定目录\n");  
  880.     printf("mkdir\t\t目录名\t\t\t在当前目录创建新目录\n");  
  881.     printf("rmdir\t\t目录名\t\t\t在当前目录删除指定目录\n");  
  882.     printf("ls\t\t无\t\t\t显示当前目录下的目录和文件\n");  
  883.     printf("create\t\t文件名\t\t\t在当前目录下创建指定文件\n");  
  884.     printf("rm\t\t文件名\t\t\t在当前目录下删除指定文件\n");  
  885.     printf("open\t\t文件名\t\t\t在当前目录下打开指定文件\n");  
  886.     printf("write\t\t无\t\t\t在打开文件状态下,写该文件\n");  
  887.     printf("read\t\t无\t\t\t在打开文件状态下,读取该文件\n");  
  888.     printf("close\t\t无\t\t\t在打开文件状态下,读取该文件\n");  
  889.     printf("exit\t\t无\t\t\t退出系统\n\n");  
  890.     printf("*********************************************************************\n\n");  
  891.     while(flag)  
  892.     {  
  893.         printf("%s>", openfilelist[curdir].dir);  
  894.         gets(s);  
  895.         cmdn = -1;  
  896.         if(strcmp(s, ""))  
  897.         {  
  898.             sp=strtok(s, " ");  
  899.             for(i = 0; i < 15; i++)  
  900.             {  
  901.                 if(strcmp(sp, cmd[i]) == 0)  
  902.                 {  
  903.                     cmdn = i;  
  904.                     break;  
  905.                 }  
  906.             }  
  907. //          printf("%d\n", cmdn);  
  908.             switch(cmdn)  
  909.             {  
  910.                 case 0:  
  911.                     sp = strtok(NULL, " ");  
  912.                     if(sp && (openfilelist[curdir].attribute & 0x20))  
  913.                         my_cd(sp);  
  914.                     else  
  915.                         printf("Please input the right command.\n");  
  916.                     break;  
  917.                 case 1:  
  918.                     sp = strtok(NULL, " ");  
  919.                     if(sp && (openfilelist[curdir].attribute & 0x20))  
  920.                         my_mkdir(sp);  
  921.                     else  
  922.                         printf("Please input the right command.\n");  
  923.                     break;  
  924.                     case 2:  
  925.                     sp = strtok(NULL, " ");  
  926.                     if(sp && (openfilelist[curdir].attribute & 0x20))  
  927.                         my_rmdir(sp);  
  928.                     else  
  929.                         printf("Please input the right command.\n");  
  930.                     break;  
  931.                 case 3:  
  932.                     if(openfilelist[curdir].attribute & 0x20)  
  933.                         my_ls();  
  934.                     else  
  935.                         printf("Please input the right command.\n");  
  936.                     break;  
  937.                 case 4:  
  938.                     sp = strtok(NULL, " ");  
  939.                     if(sp && (openfilelist[curdir].attribute & 0x20))  
  940.                         my_create(sp);  
  941.                     else  
  942.                         printf("Please input the right command.\n");  
  943.                     break;  
  944.                 case 5:  
  945.                     sp = strtok(NULL, " ");  
  946.                     if(sp && (openfilelist[curdir].attribute & 0x20))  
  947.                         my_rm(sp);  
  948.                     else  
  949.                         printf("Please input the right command.\n");  
  950.                     break;  
  951.                     case 6:  
  952.                     sp = strtok(NULL, " ");  
  953.                     if(sp && (openfilelist[curdir].attribute & 0x20))  
  954.                     {  
  955.                         if(strchr(sp, '.'))//查找sp中'.'首次出现的位置  
  956.                             curdir = my_open(sp);  
  957.                         else  
  958.                             printf("the openfile should have exname.\n");  
  959.                     }  
  960.                     else  
  961.                         printf("Please input the right command.\n");  
  962.                     break;  
  963.                 case 7:  
  964.                     if(!(openfilelist[curdir].attribute & 0x20))  
  965.                         curdir = my_close(curdir);  
  966.                     else  
  967.                         printf("No files opened.\n");  
  968.                     break;  
  969.                 case 8:  
  970.                     if(!(openfilelist[curdir].attribute & 0x20))  
  971.                         my_write(curdir);  
  972.                     else  
  973.                         printf("No files opened.\n");  
  974.                     break;  
  975.                 case 9:  
  976.                     if(!(openfilelist[curdir].attribute & 0x20))  
  977.                         my_read(curdir, openfilelist[curdir].length);  
  978.                     else  
  979.                         printf("No files opened.\n");  
  980.                     break;  
  981.                     case 10:  
  982.                     if(openfilelist[curdir].attribute & 0x20)  
  983.                     {  
  984.                         my_exitsys();  
  985.                         flag = 0;  
  986.                     }  
  987.                     else  
  988.                         printf("Please input the right command.\n");  
  989.                     break;  
  990.                 default:  
  991.                     printf("Please input the right command.\n");  
  992.                     break;  
  993.             }  
  994.         }  
  995.     }  
  996.     return 0;  
  997. }  
posted @ 2018-06-03 22:01  JackyTang  阅读(5857)  评论(0编辑  收藏  举报