【操作系统】C语言编写的FAT16文件系统
这是操作系统的期末课程设计作业之一,主要功能是在物理内存中虚拟出一个1M大小的FAT16的文件系统,然后把它读入内存中,进行具体的文件操作,具体的实用性不大,主要目的是为了练习C语言,帮助理解文件系统的特点,代码如下:
- #include <stdio.h>
- #include <malloc.h>
- #include <string.h>
- #include <time.h>
- #define BLOCKSIZE 1024 // 磁盘块大小
- #define SIZE 1024000 // 虚拟磁盘空间大小
- #define END 65535 // FAT中的文件结束标志
- #define FREE 0 // FAT中盘块空闲标志
- #define ROOTBLOCKNUM 2 // 根目录区所占盘块数
- #define MAXOPENFILE 10 // 最多同时打开文件个数t
- #define MAXTEXT 10000
- /* 文件控制块 */
- typedef struct FCB
- {
- char filename[8]; // 文件名
- char exname[3]; // 文件扩展名
- unsigned char attribute; // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件
- unsigned short time; // 文件创建时间
- unsigned short date; // 文件创建日期
- unsigned short first; // 文件起始盘块号
- unsigned long length; // 文件长度
- char free; // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配
- }fcb;
- /* 文件分配表 */
- typedef struct FAT
- {
- unsigned short id; // 磁盘块的状态(空闲的,最后的,下一个)
- }fat;
- /* 用户打开文件表 */
- typedef struct USEROPEN
- {
- char filename[8]; // 文件名
- char exname[3]; // 文件扩展名
- unsigned char attribute; // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件
- unsigned short time; // 文件创建时间
- unsigned short date; // 文件创建日期
- unsigned short first; // 文件起始盘块号
- unsigned long length; // 文件长度(对数据文件是字节数,对目录文件可以是目录项个数)
- char free; // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配
- unsigned short dirno; // 相应打开文件的目录项在父目录文件中的盘块号
- int diroff; // 相应打开文件的目录项在父目录文件的dirno盘块中的目录项序号
- char dir[80]; // 相应打开文件所在的目录名,这样方便快速检查出指定文件是否已经打开
- int father; // 父目录在打开文件表项的位置
- int count; // 读写指针在文件中的位置,文件的总字符数
- char fcbstate; // 是否修改了文件的FCB的内容,如果修改了置为1,否则为0
- char topenfile; // 表示该用户打开表项是否为空,若值为0,表示为空,否则表示已被某打开文件占据
- }useropen;
- /* 引导块 */
- typedef struct BLOCK0
- {
- char magic[10]; // 文件系统魔数
- char information[200]; // 存储一些描述信息,如磁盘块大小、磁盘块数量、最多打开文件数等
- unsigned short root; // 根目录文件的起始盘块号
- unsigned char *startblock; // 虚拟磁盘上数据区开始位置
- }block0;
- unsigned char *myvhard; // 指向虚拟磁盘的起始地址
- useropen openfilelist[MAXOPENFILE]; // 用户打开文件表数组
- int curdir; // 用户打开文件表中的当前目录所在打开文件表项的位置
- char currentdir[80]; // 记录当前目录的目录名(包括目录的路径)
- unsigned char* startp; // 记录虚拟磁盘上数据区开始位置
- char myfilename[] = "myfilesys";//文件系统的文件名
- void startsys(); // 进入文件系统
- void my_format(); // 磁盘格式化
- void my_cd(char *dirname); // 更改当前目录
- void my_mkdir(char *dirname); // 创建子目录
- void my_rmdir(char *dirname); // 删除子目录
- void my_ls(); // 显示目录
- void my_create (char *filename); // 创建文件
- void my_rm(char *filename); // 删除文件
- int my_open(char *filename); // 打开文件
- int my_close(int fd); // 关闭文件
- int my_write(int fd); // 写文件
- int do_write(int fd, char *text, int len, char wstyle); // 实际写文件
- int my_read (int fd, int len); // 读文件
- int do_read (int fd, int len,char *text); // 实际读文件
- void my_exitsys(); // 退出文件系统
- unsigned short findblock(); // 寻找空闲盘块
- int findopenfile(); // 寻找空闲文件表项
- void startsys()
- {
- FILE *fp;
- unsigned char buf[SIZE];
- fcb *root;
- int i;
- myvhard = (unsigned char *)malloc(SIZE);//申请虚拟磁盘空间
- memset(myvhard, 0, SIZE);//将myvhard中前SIZE个字节用 0 替换并返回 myvhard
- if((fp = fopen(myfilename, "r")) != NULL)
- {
- fread(buf, SIZE, 1, fp);//将二进制文件读取到缓冲区
- fclose(fp);//关闭打开的文件,缓冲区数据写入文件,释放系统提供文件资源
- if(strcmp(((block0 *)buf)->magic, "10101010"))//判断开始的8个字节内容是否为文件系统魔数
- {
- printf("myfilesys is not exist,begin to creat the file... ");
- my_format();
- }
- else
- {
- for(i = 0; i < SIZE; i++)
- myvhard[i] = buf[i];
- }
- }
- else
- {
- printf("myfilesys is not exist,begin to creat the file... ");
- my_format();
- }
- root = (fcb *)(myvhard + 5 * BLOCKSIZE);
- strcpy(openfilelist[0].filename, root->filename);
- strcpy(openfilelist[0].exname, root->exname);
- openfilelist[0].attribute = root->attribute;
- openfilelist[0].time = root->time;
- openfilelist[0].date = root->date;
- openfilelist[0].first = root->first;
- openfilelist[0].length = root->length;
- openfilelist[0].free = root->free;
- openfilelist[0].dirno = 5;
- openfilelist[0].diroff = 0;
- strcpy(openfilelist[0].dir, "\root\");
- openfilelist[0].father = 0;
- openfilelist[0].count = 0;
- openfilelist[0].fcbstate = 0;
- openfilelist[0].topenfile = 1;
- for(i = 1; i < MAXOPENFILE; i++)
- openfilelist[i].topenfile = 0;
- curdir = 0;
- strcpy(currentdir, "\root\");
- startp = ((block0 *)myvhard)->startblock;
- }
- void my_format()
- {
- FILE *fp;
- fat *fat1, *fat2;
- block0 *blk0;
- time_t now;
- struct tm *nowtime;
- fcb *root;
- int i;
- blk0 = (block0 *)myvhard;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
- root = (fcb *)(myvhard + 5 * BLOCKSIZE);
- strcpy(blk0->magic, "10101010");
- strcpy(blk0->information, "My FileSystem Ver 1.0 Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2 ");
- blk0->root = 5;
- blk0->startblock = (unsigned char *)root;
- for(i = 0; i < 5; i++)
- {
- fat1->id = END;
- fat2->id = END;
- fat1++;
- fat2++;
- }
- fat1->id = 6;
- fat2->id = 6;
- fat1++;
- fat2++;
- fat1->id = END;
- fat2->id = END;
- fat1++;
- fat2++;
- for(i = 7; i < SIZE / BLOCKSIZE; i++)
- {
- fat1->id = FREE;
- fat2->id = FREE;
- fat1++;
- fat2++;
- }
- now = time(NULL);
- nowtime = localtime(&now);
- strcpy(root->filename, ".");
- strcpy(root->exname, "");
- root->attribute = 0x28;
- root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
- root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
- root->first = 5;
- root->length = 2 * sizeof(fcb);
- root->free = 1;
- root++;
- now = time(NULL);
- nowtime = localtime(&now);
- strcpy(root->filename, "..");
- strcpy(root->exname, "");
- root->attribute = 0x28;
- root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
- root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
- root->first = 5;
- root->length = 2 * sizeof(fcb);
- root->free = 1;
- fp = fopen(myfilename, "w");
- fwrite(myvhard, SIZE, 1, fp);
- fclose(fp);
- }
- void my_cd(char *dirname)
- {
- char *dir;
- int fd;
- dir = strtok(dirname, "\");//分解字符串为一组字符串。dirname为要分解的字符串,"\"为分隔符字符串
- if(strcmp(dir, ".") == 0)
- return;
- else if(strcmp(dir, "..") == 0)
- {
- if(curdir)
- curdir = my_close(curdir);
- return;
- }
- else if(strcmp(dir, "root") == 0)
- {
- while(curdir)
- curdir = my_close(curdir);
- dir = strtok(NULL, "\");
- }
- while(dir)
- {
- fd = my_open(dir);
- if(fd != -1)
- curdir = fd;
- else
- return;
- dir = strtok(NULL, "\");
- }
- }
- void my_mkdir(char *dirname)
- {
- fcb *fcbptr;
- fat *fat1, *fat2;
- time_t now;
- struct tm *nowtime;
- char text[MAXTEXT];
- unsigned short blkno;
- int rbn, fd, i;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
- openfilelist[curdir].count = 0;
- rbn = do_read(curdir, openfilelist[curdir].length, text);
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)//在当前目录下找,是否有重名目录
- {
- if(strcmp(fcbptr->filename, dirname) == 0 && strcmp(fcbptr->exname, "") == 0)
- {
- printf("Error,the dirname is already exist! ");
- return;
- }
- fcbptr++;
- }
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)
- {
- if(fcbptr->free == 0)
- break;
- fcbptr++;
- }
- blkno = findblock();//寻找空闲盘块
- if(blkno == -1)
- return;
- (fat1 + blkno)->id = END;
- (fat2 + blkno)->id = END;
- now = time(NULL);
- nowtime = localtime(&now);
- strcpy(fcbptr->filename, dirname);
- strcpy(fcbptr->exname, "");
- fcbptr->attribute = 0x30;
- fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
- fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
- fcbptr->first = blkno;
- fcbptr->length = 2 * sizeof(fcb);
- fcbptr->free = 1;
- openfilelist[curdir].count = i * sizeof(fcb);
- do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
- fd = my_open(dirname);//建立新目录的'.','..'目录
- if(fd == -1)
- return;
- fcbptr = (fcb *)malloc(sizeof(fcb));
- now = time(NULL);
- nowtime = localtime(&now);
- strcpy(fcbptr->filename, ".");
- strcpy(fcbptr->exname, "");
- fcbptr->attribute = 0x28;
- fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
- fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
- fcbptr->first = blkno;
- fcbptr->length = 2 * sizeof(fcb);
- fcbptr->free = 1;
- do_write(fd, (char *)fcbptr, sizeof(fcb), 2);
- now = time(NULL);
- nowtime = localtime(&now);
- strcpy(fcbptr->filename, "..");
- strcpy(fcbptr->exname, "");
- fcbptr->attribute = 0x28;
- fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
- fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
- fcbptr->first = blkno;
- fcbptr->length = 2 * sizeof(fcb);
- fcbptr->free = 1;
- do_write(fd, (char *)fcbptr, sizeof(fcb), 2);
- free(fcbptr);
- my_close(fd);
- fcbptr = (fcb *)text;
- fcbptr->length = openfilelist[curdir].length;
- openfilelist[curdir].count = 0;
- do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
- openfilelist[curdir].fcbstate = 1;
- }
- void my_rmdir(char *dirname)
- {
- fcb *fcbptr,*fcbptr2;
- fat *fat1, *fat2, *fatptr1, *fatptr2;
- char text[MAXTEXT], text2[MAXTEXT];
- unsigned short blkno;
- int rbn, rbn2, fd, i, j;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
- if(strcmp(dirname, ".") == 0 || strcmp(dirname, "..") == 0)
- {
- printf("Error,can't remove this directory. ");
- return;
- }
- openfilelist[curdir].count = 0;
- rbn = do_read(curdir, openfilelist[curdir].length, text);
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)//查找要删除的目录
- {
- if(strcmp(fcbptr->filename, dirname) == 0 && strcmp(fcbptr->exname, "") == 0)
- break;
- fcbptr++;
- }
- if(i == rbn / sizeof(fcb))
- {
- printf("Error,the directory is not exist. ");
- return;
- }
- fd = my_open(dirname);
- rbn2 = do_read(fd, openfilelist[fd].length, text2);
- fcbptr2 = (fcb *)text2;
- for(j = 0; j < rbn2 / sizeof(fcb); j++)//判断要删除目录是否为空
- {
- if(strcmp(fcbptr2->filename, ".") && strcmp(fcbptr2->filename, "..") && strcmp(fcbptr2->filename, ""))
- {
- my_close(fd);
- printf("Error,the directory is not empty. ");
- return;
- }
- fcbptr2++;
- }
- blkno = openfilelist[fd].first;
- while(blkno != END)
- {
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- blkno = fatptr1->id;
- fatptr1->id = FREE;
- fatptr2->id = FREE;
- }
- my_close(fd);
- strcpy(fcbptr->filename, "");
- fcbptr->free = 0;
- openfilelist[curdir].count = i * sizeof(fcb);
- do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
- openfilelist[curdir].fcbstate = 1;
- }
- void my_ls()
- {
- fcb *fcbptr;
- char text[MAXTEXT];
- int rbn, i;
- openfilelist[curdir].count = 0;
- rbn = do_read(curdir, openfilelist[curdir].length, text);
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)
- {
- if(fcbptr->free)
- {
- if(fcbptr->attribute & 0x20)
- 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);
- else
- 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);
- }
- fcbptr++;
- }
- }
- void my_create(char *filename)
- {
- fcb *fcbptr;
- fat *fat1, *fat2;
- char *fname, *exname, text[MAXTEXT];
- unsigned short blkno;
- int rbn, i;
- time_t now;
- struct tm *nowtime;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- fat2 = (fat *)(myvhard + BLOCKSIZE);
- fname = strtok(filename, ".");
- exname = strtok(NULL, ".");
- if(strcmp(fname, "") == 0)
- {
- printf("Error,creating file must have a right name. ");
- return;
- }
- if(!exname)
- {
- printf("Error,creating file must have a extern name. ");
- return;
- }
- openfilelist[curdir].count = 0;
- rbn = do_read(curdir, openfilelist[curdir].length, text);
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)
- {
- if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
- {
- printf("Error,the filename is already exist! ");
- return;
- }
- fcbptr++;
- }
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)
- {
- if(fcbptr->free == 0)
- break;
- fcbptr++;
- }
- blkno = findblock();
- if(blkno == -1)
- return;
- (fat1 + blkno)->id = END;
- (fat2 + blkno)->id = END;
- now = time(NULL);
- nowtime = localtime(&now);
- strcpy(fcbptr->filename, fname);
- strcpy(fcbptr->exname, exname);
- fcbptr->attribute = 0x00;
- fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
- fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
- fcbptr->first = blkno;
- fcbptr->length = 0;
- fcbptr->free = 1;
- openfilelist[curdir].count = i * sizeof(fcb);
- do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
- fcbptr = (fcb *)text;
- fcbptr->length = openfilelist[curdir].length;
- openfilelist[curdir].count = 0;
- do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
- openfilelist[curdir].fcbstate = 1;
- }
- void my_rm(char *filename)
- {
- fcb *fcbptr;
- fat *fat1, *fat2, *fatptr1, *fatptr2;
- char *fname, *exname, text[MAXTEXT];
- unsigned short blkno;
- int rbn, i;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
- fname = strtok(filename, ".");
- exname = strtok(NULL, ".");
- if(strcmp(fname, "") == 0)
- {
- printf("Error,removing file must have a right name. ");
- return;
- }
- if(!exname)
- {
- printf("Error,removing file must have a extern name. ");
- return;
- }
- openfilelist[curdir].count = 0;
- rbn = do_read(curdir, openfilelist[curdir].length, text);
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)
- {
- if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
- break;
- fcbptr++;
- }
- if(i == rbn / sizeof(fcb))
- {
- printf("Error,the file is not exist. ");
- return;
- }
- openfilelist[curdir].count = 0;
- rbn = do_read(curdir, openfilelist[curdir].length, text);
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)
- {
- if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
- break;
- fcbptr++;
- }
- if(i == rbn / sizeof(fcb))
- {
- printf("Error,the file is not exist. ");
- return;
- }
- blkno = fcbptr->first;
- while(blkno != END)
- {
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- blkno = fatptr1->id;
- fatptr1->id = FREE;
- fatptr2->id = FREE;
- }
- strcpy(fcbptr->filename, "");
- fcbptr->free = 0;
- openfilelist[curdir].count = i * sizeof(fcb);
- do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
- openfilelist[curdir].fcbstate = 1;
- }
- int my_open(char *filename)
- {
- fcb *fcbptr;
- char *fname, exname[3], *str, text[MAXTEXT];
- int rbn, fd, i;
- fname = strtok(filename, ".");
- str = strtok(NULL, ".");
- if(str)
- strcpy(exname, str);
- else
- strcpy(exname, "");
- for(i = 0; i < MAXOPENFILE; i++)
- {
- if(strcmp(openfilelist[i].filename, fname) == 0 && strcmp(openfilelist[i].exname, exname) == 0 && i != curdir)
- {
- printf("Error,the file is already open. ");
- return -1;
- }
- }
- openfilelist[curdir].count = 0;
- rbn = do_read(curdir, openfilelist[curdir].length, text);
- fcbptr = (fcb *)text;
- for(i = 0; i < rbn / sizeof(fcb); i++)
- {
- if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
- break;
- fcbptr++;
- }
- if(i == rbn / sizeof(fcb))
- {
- printf("Error,the file is not exist. ");
- return -1;
- }
- fd = findopenfile();
- if(fd == -1)
- return -1;
- strcpy(openfilelist[fd].filename, fcbptr->filename);
- strcpy(openfilelist[fd].exname, fcbptr->exname);
- openfilelist[fd].attribute = fcbptr->attribute;
- openfilelist[fd].time = fcbptr->time;
- openfilelist[fd].date = fcbptr->date;
- openfilelist[fd].first = fcbptr->first;
- openfilelist[fd].length = fcbptr->length;
- openfilelist[fd].free = fcbptr->free;
- openfilelist[fd].dirno = openfilelist[curdir].first;
- openfilelist[fd].diroff = i;
- strcpy(openfilelist[fd].dir, openfilelist[curdir].dir);
- strcat(openfilelist[fd].dir, filename);
- if(fcbptr->attribute & 0x20)
- strcat(openfilelist[fd].dir, "\");
- openfilelist[fd].father = curdir;
- openfilelist[fd].count = 0;
- openfilelist[fd].fcbstate = 0;
- openfilelist[fd].topenfile = 1;
- return fd;
- }
- int my_close(int fd)
- {
- fcb *fcbptr;
- int father;
- if(fd < 0 || fd >= MAXOPENFILE)
- {
- printf("Error,the file is not exist. ");
- return -1;
- }
- if(openfilelist[fd].fcbstate)
- {
- fcbptr = (fcb *)malloc(sizeof(fcb));
- strcpy(fcbptr->filename, openfilelist[fd].filename);
- strcpy(fcbptr->exname, openfilelist[fd].exname);
- fcbptr->attribute = openfilelist[fd].attribute;
- fcbptr->time = openfilelist[fd].time;
- fcbptr->date = openfilelist[fd].date;
- fcbptr->first = openfilelist[fd].first;
- fcbptr->length = openfilelist[fd].length;
- fcbptr->free = openfilelist[fd].free;
- father = openfilelist[fd].father;
- openfilelist[father].count = openfilelist[fd].diroff * sizeof(fcb);
- do_write(father, (char *)fcbptr, sizeof(fcb), 2);
- free(fcbptr);
- openfilelist[fd].fcbstate = 0;
- }
- strcpy(openfilelist[fd].filename, "");
- strcpy(openfilelist[fd].exname, "");
- openfilelist[fd].topenfile = 0;
- return father;
- }
- int my_write(int fd)
- {
- fat *fat1, *fat2, *fatptr1, *fatptr2;
- int wstyle, len, ll, tmp;
- char text[MAXTEXT];
- unsigned short blkno;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
- if(fd < 0 || fd >= MAXOPENFILE)
- {
- printf("The file is not exist! ");
- return -1;
- }
- while(1)
- {
- printf("Please enter the number of write style: 1.cut write 2.cover write 3.add write ");
- scanf("%d", &wstyle);
- if(wstyle > 0 && wstyle < 4)
- break;
- printf("Input Error!");
- }
- getchar();
- switch(wstyle)
- {
- case 1:
- blkno = openfilelist[fd].first;
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- blkno = fatptr1->id;
- fatptr1->id = END;
- fatptr2->id = END;
- while(blkno != END)
- {
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- blkno = fatptr1->id;
- fatptr1->id = FREE;
- fatptr2->id = FREE;
- }
- openfilelist[fd].count = 0;
- openfilelist[fd].length = 0;
- break;
- case 2:
- openfilelist[fd].count = 0;
- break;
- case 3:
- openfilelist[fd].count = openfilelist[fd].length;
- break;
- default:
- break;
- }
- ll = 0;
- printf("please input write data(end with Ctrl+Z): ");
- while(gets(text))
- {
- len = strlen(text);
- text[len++] = ' ';
- text[len] = ' ';
- tmp = do_write(fd, text, len, wstyle);
- if(tmp != -1)
- ll += tmp;
- if(tmp < len)
- {
- printf("Wirte Error!");
- break;
- }
- }
- return ll;
- }
- int do_write(int fd, char *text, int len, char wstyle)
- {
- fat *fat1, *fat2, *fatptr1, *fatptr2;
- unsigned char *buf, *blkptr;
- unsigned short blkno, blkoff;
- int i, ll;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
- buf = (unsigned char *)malloc(BLOCKSIZE);
- if(buf == NULL)
- {
- printf("malloc failed! ");
- return -1;
- }
- blkno = openfilelist[fd].first;
- blkoff = openfilelist[fd].count;
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- while(blkoff >= BLOCKSIZE)
- {
- blkno = fatptr1->id;
- if(blkno == END)
- {
- blkno = findblock();
- if(blkno == -1)
- {
- free(buf);
- return -1;
- }
- fatptr1->id = blkno;
- fatptr2->id = blkno;
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- fatptr1->id = END;
- fatptr2->id = END;
- }
- else
- {
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- }
- blkoff = blkoff - BLOCKSIZE;
- }
- ll = 0;
- while(ll < len)
- {
- blkptr = (unsigned char *)(myvhard + blkno * BLOCKSIZE);
- for(i = 0; i < BLOCKSIZE; i++)
- buf[i] = blkptr[i];
- for(;blkoff < BLOCKSIZE; blkoff++)
- {
- buf[blkoff] = text[ll++];
- openfilelist[fd].count++;
- if(ll == len)
- break;
- }
- for(i = 0; i < BLOCKSIZE; i++)
- blkptr[i] = buf[i];
- if(ll < len)
- {
- blkno = fatptr1->id;
- if(blkno == END)
- {
- blkno = findblock();
- if(blkno == -1)
- break;
- fatptr1->id = blkno;
- fatptr2->id = blkno;
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- fatptr1->id = END;
- fatptr2->id = END;
- }
- else
- {
- fatptr1 = fat1 + blkno;
- fatptr2 = fat2 + blkno;
- }
- blkoff = 0;
- }
- }
- if(openfilelist[fd].count > openfilelist[fd].length)
- openfilelist[fd].length = openfilelist[fd].count;
- openfilelist[fd].fcbstate = 1;
- free(buf);
- return ll;
- }
- int my_read(int fd, int len)
- {
- char text[MAXTEXT];
- int ll;
- if(fd < 0 || fd >= MAXOPENFILE)
- {
- printf("The File is not exist! ");
- return -1;
- }
- openfilelist[fd].count = 0;
- ll = do_read(fd, len, text);
- if(ll != -1)
- printf("%s", text);
- else
- printf("Read Error! ");
- return ll;
- }
- int do_read(int fd, int len, char *text)
- {
- fat *fat1, *fatptr;
- unsigned char *buf, *blkptr;
- unsigned short blkno, blkoff;
- int i, ll;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- buf = (unsigned char *)malloc(BLOCKSIZE);
- if(buf == NULL)
- {
- printf("malloc failed! ");
- return -1;
- }
- blkno = openfilelist[fd].first;
- blkoff = openfilelist[fd].count;
- if(blkoff >= openfilelist[fd].length)
- {
- puts("Read out of range!");
- free(buf);
- return -1;
- }
- fatptr = fat1 + blkno;
- while(blkoff >= BLOCKSIZE)
- {
- blkno = fatptr->id;
- blkoff = blkoff - BLOCKSIZE;
- fatptr = fat1 + blkno;
- }
- ll = 0;
- while(ll < len)
- {
- blkptr = (unsigned char *)(myvhard + blkno * BLOCKSIZE);
- for(i = 0; i < BLOCKSIZE; i++)
- buf[i] = blkptr[i];
- for(; blkoff < BLOCKSIZE; blkoff++)
- {
- text[ll++] = buf[blkoff];
- openfilelist[fd].count++;
- if(ll == len || openfilelist[fd].count == openfilelist[fd].length)
- break;
- }
- if(ll < len && openfilelist[fd].count != openfilelist[fd].length)
- {
- blkno = fatptr->id;
- if(blkno == END)
- break;
- blkoff = 0;
- fatptr = fat1 + blkno;
- }
- }
- text[ll] = ' ';
- free(buf);
- return ll;
- }
- void my_exitsys()
- {
- FILE *fp;
- while(curdir)
- curdir = my_close(curdir);
- fp = fopen(myfilename, "w");
- fwrite(myvhard, SIZE, 1, fp);
- fclose(fp);
- free(myvhard);
- }
- unsigned short findblock()
- {
- unsigned short i;
- fat *fat1, *fatptr;
- fat1 = (fat *)(myvhard + BLOCKSIZE);
- for(i = 7; i < SIZE / BLOCKSIZE; i++)
- {
- fatptr = fat1 + i;
- if(fatptr->id == FREE)
- return i;
- }
- printf("Error,Can't find free block! ");
- return -1;
- }
- int findopenfile()
- {
- int i;
- for(i = 0; i < MAXTEXT; i++)
- {
- if(openfilelist[i].topenfile == 0)
- return i;
- }
- printf("Error,open too many files! ");
- return -1;
- }
- int main()
- {
- char cmd[15][10] = {"cd", "mkdir", "rmdir", "ls", "create", "rm", "open", "close", "write", "read", "exit"};
- char s[30], *sp;
- int cmdn, flag = 1, i;
- startsys();
- printf("*********************File System V1.0******************************* ");
- printf("命令名 命令参数 命令说明 ");
- printf("cd 目录名(路径名) 切换当前目录到指定目录 ");
- printf("mkdir 目录名 在当前目录创建新目录 ");
- printf("rmdir 目录名 在当前目录删除指定目录 ");
- printf("ls 无 显示当前目录下的目录和文件 ");
- printf("create 文件名 在当前目录下创建指定文件 ");
- printf("rm 文件名 在当前目录下删除指定文件 ");
- printf("open 文件名 在当前目录下打开指定文件 ");
- printf("write 无 在打开文件状态下,写该文件 ");
- printf("read 无 在打开文件状态下,读取该文件 ");
- printf("close 无 在打开文件状态下,读取该文件 ");
- printf("exit 无 退出系统 ");
- printf("********************************************************************* ");
- while(flag)
- {
- printf("%s>", openfilelist[curdir].dir);
- gets(s);
- cmdn = -1;
- if(strcmp(s, ""))
- {
- sp=strtok(s, " ");
- for(i = 0; i < 15; i++)
- {
- if(strcmp(sp, cmd[i]) == 0)
- {
- cmdn = i;
- break;
- }
- }
- // printf("%d ", cmdn);
- switch(cmdn)
- {
- case 0:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_cd(sp);
- else
- printf("Please input the right command. ");
- break;
- case 1:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_mkdir(sp);
- else
- printf("Please input the right command. ");
- break;
- case 2:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_rmdir(sp);
- else
- printf("Please input the right command. ");
- break;
- case 3:
- if(openfilelist[curdir].attribute & 0x20)
- my_ls();
- else
- printf("Please input the right command. ");
- break;
- case 4:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_create(sp);
- else
- printf("Please input the right command. ");
- break;
- case 5:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_rm(sp);
- else
- printf("Please input the right command. ");
- break;
- case 6:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- {
- if(strchr(sp, '.'))//查找sp中'.'首次出现的位置
- curdir = my_open(sp);
- else
- printf("the openfile should have exname. ");
- }
- else
- printf("Please input the right command. ");
- break;
- case 7:
- if(!(openfilelist[curdir].attribute & 0x20))
- curdir = my_close(curdir);
- else
- printf("No files opened. ");
- break;
- case 8:
- if(!(openfilelist[curdir].attribute & 0x20))
- my_write(curdir);
- else
- printf("No files opened. ");
- break;
- case 9:
- if(!(openfilelist[curdir].attribute & 0x20))
- my_read(curdir, openfilelist[curdir].length);
- else
- printf("No files opened. ");
- break;
- case 10:
- if(openfilelist[curdir].attribute & 0x20)
- {
- my_exitsys();
- flag = 0;
- }
- else
- printf("Please input the right command. ");
- break;
- default:
- printf("Please input the right command. ");
- break;
- }
- }
- }
- return 0;
- }