• 【操作系统】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... ");  
    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... ");  
    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   Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2 ");  
    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! ");  
    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. ");  
    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. ");  
    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. ");  
    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\ <DIR> %d/%d/%d %02d:%02d:%02d ", 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 %dB %d/%d/%d %02d:%02d:%02d ", 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. ");  
    405.         return;  
    406.     }  
    407.     if(!exname)  
    408.     {  
    409.         printf("Error,creating file must have a extern name. ");  
    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! ");  
    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. ");  
    469.         return;  
    470.     }  
    471.     if(!exname)  
    472.     {  
    473.         printf("Error,removing file must have a extern name. ");  
    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. ");  
    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. ");  
    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. ");  
    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. ");  
    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. ");  
    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! ");  
    617.         return -1;  
    618.     }  
    619.     while(1)  
    620.     {  
    621.         printf("Please enter the number of write style: 1.cut write 2.cover write 3.add write ");  
    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): ");  
    659.     while(gets(text))  
    660.     {  
    661.         len = strlen(text);  
    662.         text[len++] = ' ';  
    663.         text[len] = '';  
    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! ");  
    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! ");  
    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! ");  
    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! ");  
    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] = '';  
    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! ");  
    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! ");  
    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******************************* ");  
    878.     printf("命令名 命令参数 命令说明 ");  
    879.     printf("cd 目录名(路径名) 切换当前目录到指定目录 ");  
    880.     printf("mkdir 目录名 在当前目录创建新目录 ");  
    881.     printf("rmdir 目录名 在当前目录删除指定目录 ");  
    882.     printf("ls 无 显示当前目录下的目录和文件 ");  
    883.     printf("create 文件名 在当前目录下创建指定文件 ");  
    884.     printf("rm 文件名 在当前目录下删除指定文件 ");  
    885.     printf("open 文件名 在当前目录下打开指定文件 ");  
    886.     printf("write 无 在打开文件状态下,写该文件 ");  
    887.     printf("read 无 在打开文件状态下,读取该文件 ");  
    888.     printf("close 无 在打开文件状态下,读取该文件 ");  
    889.     printf("exit 无 退出系统 ");  
    890.     printf("********************************************************************* ");  
    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 ", 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. ");  
    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. ");  
    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. ");  
    930.                     break;  
    931.                 case 3:  
    932.                     if(openfilelist[curdir].attribute & 0x20)  
    933.                         my_ls();  
    934.                     else  
    935.                         printf("Please input the right command. ");  
    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. ");  
    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. ");  
    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. ");  
    959.                     }  
    960.                     else  
    961.                         printf("Please input the right command. ");  
    962.                     break;  
    963.                 case 7:  
    964.                     if(!(openfilelist[curdir].attribute & 0x20))  
    965.                         curdir = my_close(curdir);  
    966.                     else  
    967.                         printf("No files opened. ");  
    968.                     break;  
    969.                 case 8:  
    970.                     if(!(openfilelist[curdir].attribute & 0x20))  
    971.                         my_write(curdir);  
    972.                     else  
    973.                         printf("No files opened. ");  
    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. ");  
    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. ");  
    989.                     break;  
    990.                 default:  
    991.                     printf("Please input the right command. ");  
    992.                     break;  
    993.             }  
    994.         }  
    995.     }  
    996.     return 0;  
    997. }  
  • 相关阅读:
    ES6 数值类型常用方法
    阿里云如何发布网站
    常用的网站推荐
    笔记一 sql 基础知识
    笔记一 MVC初识
    基础二 面向对象编程
    基础一
    css reset 样式
    CSS 嵌套绝对定位
    ADO
  • 原文地址:https://www.cnblogs.com/jackytang/p/9130734.html
Copyright © 2020-2023  润新知