【操作系統】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...\n");
- my_format();
- }
- else
- {
- for(i = 0; i < SIZE; i++)
- myvhard[i] = buf[i];
- }
- }
- else
- {
- printf("myfilesys is not exist,begin to creat the file...\n");
- 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 \n Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2\n");
- 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!\n");
- 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.\n");
- 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.\n");
- 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.\n");
- 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\\\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);
- else
- 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);
- }
- 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.\n");
- return;
- }
- if(!exname)
- {
- printf("Error,creating file must have a extern name.\n");
- 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!\n");
- 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.\n");
- return;
- }
- if(!exname)
- {
- printf("Error,removing file must have a extern name.\n");
- 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.\n");
- 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.\n");
- 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.\n");
- 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.\n");
- 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.\n");
- 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!\n");
- return -1;
- }
- while(1)
- {
- printf("Please enter the number of write style:\n1.cut write\t2.cover write\t3.add write\n");
- 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):\n");
- while(gets(text))
- {
- len = strlen(text);
- text[len++] = '\n';
- text[len] = '\0';
- 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!\n");
- 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!\n");
- return -1;
- }
- openfilelist[fd].count = 0;
- ll = do_read(fd, len, text);
- if(ll != -1)
- printf("%s", text);
- else
- printf("Read Error!\n");
- 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!\n");
- 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] = '\0';
- 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!\n");
- 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!\n");
- 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*******************************\n\n");
- printf("命令名\t\t命令參數\t\t命令說明\n\n");
- printf("cd\t\t目錄名(路徑名)\t\t切換當前目錄到指定目錄\n");
- printf("mkdir\t\t目錄名\t\t\t在當前目錄創建新目錄\n");
- printf("rmdir\t\t目錄名\t\t\t在當前目錄刪除指定目錄\n");
- printf("ls\t\t無\t\t\t顯示當前目錄下的目錄和文件\n");
- printf("create\t\t文件名\t\t\t在當前目錄下創建指定文件\n");
- printf("rm\t\t文件名\t\t\t在當前目錄下刪除指定文件\n");
- printf("open\t\t文件名\t\t\t在當前目錄下打開指定文件\n");
- printf("write\t\t無\t\t\t在打開文件狀態下,寫該文件\n");
- printf("read\t\t無\t\t\t在打開文件狀態下,讀取該文件\n");
- printf("close\t\t無\t\t\t在打開文件狀態下,讀取該文件\n");
- printf("exit\t\t無\t\t\t退出系統\n\n");
- printf("*********************************************************************\n\n");
- 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\n", cmdn);
- switch(cmdn)
- {
- case 0:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_cd(sp);
- else
- printf("Please input the right command.\n");
- break;
- case 1:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_mkdir(sp);
- else
- printf("Please input the right command.\n");
- break;
- case 2:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_rmdir(sp);
- else
- printf("Please input the right command.\n");
- break;
- case 3:
- if(openfilelist[curdir].attribute & 0x20)
- my_ls();
- else
- printf("Please input the right command.\n");
- break;
- case 4:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_create(sp);
- else
- printf("Please input the right command.\n");
- break;
- case 5:
- sp = strtok(NULL, " ");
- if(sp && (openfilelist[curdir].attribute & 0x20))
- my_rm(sp);
- else
- printf("Please input the right command.\n");
- 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.\n");
- }
- else
- printf("Please input the right command.\n");
- break;
- case 7:
- if(!(openfilelist[curdir].attribute & 0x20))
- curdir = my_close(curdir);
- else
- printf("No files opened.\n");
- break;
- case 8:
- if(!(openfilelist[curdir].attribute & 0x20))
- my_write(curdir);
- else
- printf("No files opened.\n");
- break;
- case 9:
- if(!(openfilelist[curdir].attribute & 0x20))
- my_read(curdir, openfilelist[curdir].length);
- else
- printf("No files opened.\n");
- break;
- case 10:
- if(openfilelist[curdir].attribute & 0x20)
- {
- my_exitsys();
- flag = 0;
- }
- else
- printf("Please input the right command.\n");
- break;
- default:
- printf("Please input the right command.\n");
- break;
- }
- }
- }
- return 0;
- }