文件系统

这个代码讲道理 不是我写的
我是了别人的代码 然后自己借鉴了后重写的
并修了3,4个bug,并且剪短了很多
可以rmdir该目录以及所有下属,可以cd多层目录

三个问题,
1.一个目录文件只删中间一部分,我的写发是这时length不变的,最好修改为read遍历对于free的文件直接跳过(想了想这也不好解决)
2.和老师还讨论了一个问题,如果close了父亲,那么儿子就找不到父亲了,这个可以通过我觉得可以在fcb中加int dirno;int diroff;
3.覆盖写的用处不大,感觉可以修改下write

#include<bits/stdc++.h>
using namespace std;
#define BLOCKSIZE     1024
#define SIZE          1024000
#define END           65535
#define FREE          0
#define MAXOPENFILE   10
#define MAX_TEXT_SIZE 10000

typedef struct FCB {
    char filename[8];
    char exname[5];
    unsigned char attribute;
    unsigned short time;
    unsigned short date;
    unsigned short first;
    unsigned long length;
    char free;
} fcb;
typedef struct FAT{
    unsigned short id;
} fat;
typedef struct USEROPEN {
    char filename[8];
    char exname[5];
    unsigned char attribute;
    unsigned short time;
    unsigned short date;
    unsigned short first;
    unsigned long length;
    char free;

    int dirno;
    int diroff;
    char dir[80];
    int off;
    char fcbstate;
    char topenfile;
} useropen;
typedef struct BLOCK0 {
    char magic_number[8];
    char information[200];
    unsigned short root;
    unsigned char *startblock;
} block0;
unsigned char *myvhard;
useropen openfilelist[MAXOPENFILE];
int currfd;
unsigned char *startp;
char *FileName = "basasuya.txt";

void setZero(fcb *fcbPtr) {
    fcbPtr->date = 0;
    fcbPtr->time = 0;
    fcbPtr->exname[0] = '\0';
    fcbPtr->filename[0] = '\0';
    fcbPtr->first = 0;
    fcbPtr->free = 0;
    fcbPtr->length = 0;
}
int getFreeOpenfilelist() {
    for(int i = 0; i < MAXOPENFILE; ++i) {
        if(openfilelist[i].topenfile == 0) {
            openfilelist[i].topenfile = 1;
            return i;
        }
    }
    return -1;
}
unsigned short getFreeBLOCK() {
    fat* fat1 = (fat*)(myvhard + BLOCKSIZE);
    for(int i = 0; i < (int)(SIZE/BLOCKSIZE); ++i) {
        if(fat1[i].id == FREE) {
            return i;
        }
    }
    return END;
}
int find_father_dir(int fd) {
    for(int i = 0; i < MAXOPENFILE; ++i) {
        if(openfilelist[i].first == openfilelist[fd].dirno && openfilelist[i].topenfile == 1) {
            return i;
        }
    }
    return -1;
}
void my_format() {
    block0 *boot = (block0 *)myvhard;
    strcpy(boot->magic_number,"10101010");
    strcpy(boot->information,"0:引导块 1,2:FAT1 3,4:FAT2 数据");
    boot->root = 5;
    boot->startblock = myvhard + BLOCKSIZE*5;

    fat* fat1 = (fat*)(myvhard + BLOCKSIZE);
    for(int i = 0; i <= 5; ++i) {
        fat1[i].id = END;
    }
    for(int i = 6; i < 1000; ++i) {
        fat1[i].id = FREE;
    }
    fat* fat2 = (fat*)(myvhard + BLOCKSIZE*3);
    memcpy(fat2, fat1, BLOCKSIZE);

    fcb *root = (fcb*)(myvhard + BLOCKSIZE*5);

    strcpy(root->filename,".");
    strcpy(root->exname,"di");
    root->attribute = 0;
    time_t rawTime = time(NULL);
    struct tm *time = localtime(&rawTime);
    root->time = time->tm_hour * 2048 + time->tm_min*32 + time->tm_sec/2;
    root->date = (time->tm_year-100)*512 + (time->tm_mon+1)*32 + (time->tm_mday);
    root->first = 5; root->free = 1;
    root->length = 2*sizeof(fcb);
    fcb* root2 = root+1;
    memcpy(root2, root, sizeof(fcb));
    strcpy(root2->filename, "..");

    for(int i = 2; i < int(BLOCKSIZE / sizeof(fcb)); ++i) { // let the whole fcb be zero
        root2 ++; strcpy(root2->filename, "");
        root2->free = 0;
    }
    FILE *fp = fopen(FileName, "w");
    fwrite(myvhard, SIZE, 1, fp);
    fclose(fp);
}
void startSys() {
    unsigned char buffer[SIZE];
    myvhard = (unsigned char *)malloc(SIZE);
    FILE *file;
    if((file = fopen(FileName, "r")) != NULL) {
        fread(buffer, SIZE, 1, file);
        if(memcmp(buffer, "10101010", 8) != 0) {
            my_format();
        }
        else memcpy(myvhard, buffer, SIZE);
        fclose(file);
    }else {
        my_format();
    }
    fcb *root;
    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].off = 0;
    openfilelist[0].fcbstate = 0;
    openfilelist[0].topenfile = 1;
    startp = ((block0*)myvhard)->startblock;
    currfd = 0;
    return ;
}
int doread(int fd, int len, char *text) {
    int lenTmp = len;
    unsigned char* buf = (unsigned char*)malloc(1024);
    if(buf == NULL) {
        printf("do_read申请空间失败\n"); return -1;
    }
    int off = openfilelist[fd].off;
    int blockNum = openfilelist[fd].first;
    fat* fatPtr = (fat *)(myvhard+BLOCKSIZE) + blockNum;
    while(off >= BLOCKSIZE) {
        off -= BLOCKSIZE;
        blockNum = fatPtr->id;
        if(blockNum == END) {
            printf("do_read寻找的块不存在\n"); return -1;
        }
        fatPtr = (fat*)(myvhard + BLOCKSIZE) + blockNum;
    }
    unsigned char* blockPtr = myvhard +BLOCKSIZE*blockNum;
    memcpy(buf, blockPtr, BLOCKSIZE);
    char *textPtr = text;
    while(len > 0) {
        if(BLOCKSIZE - off > len) {
            memcpy(textPtr,buf+off, len);
            textPtr += len;
            off += len;
            openfilelist[fd].off += len;
            len = 0;
        }else {
            memcpy(textPtr, buf+off, BLOCKSIZE-off);
            textPtr += BLOCKSIZE - off;
            off = 0;
            len -= BLOCKSIZE - off;
            blockNum = fatPtr->id;
            if(blockNum == END) {
                printf("len 长度过长,超过文件限制!\n"); break;
            }
            fatPtr = (fat*)(myvhard + BLOCKSIZE) + blockNum;
            blockPtr = myvhard + BLOCKSIZE*blockNum;
            memcpy(buf, blockPtr, BLOCKSIZE);
        }
    }
    free(buf);
    return lenTmp - len;
}
void Read(int fd) {
    if(fd >= MAXOPENFILE || fd < 0) {
        printf("文件不存在\n");
        return ;
    }
    openfilelist[fd].off = 0;
    char text[MAX_TEXT_SIZE] = "\0";
    doread(fd, openfilelist[fd].length, text);
    printf("%s\n",text);
}
int dowrite(int fd, char *text, int len, char wstyle) {
    int blockNum = openfilelist[fd].first;
    fat *fatPtr = (fat*)(myvhard + BLOCKSIZE) + blockNum;
    fat* fat1 = (fat*)(myvhard+BLOCKSIZE);
    if(wstyle == 0) {
        openfilelist[fd].off = 0; openfilelist[fd].length = 0;
    }else if(wstyle == 1) {
        if(openfilelist[fd].attribute == 1 && openfilelist[fd].length != 0 && openfilelist[fd].off != 0) {
            openfilelist[fd].off --;
        }
    }else {
        if(openfilelist[fd].attribute == 0) {
            openfilelist[fd].off = openfilelist[fd].length;
        }else if(openfilelist[fd].attribute == 1 && openfilelist[fd].length != 0) {
            openfilelist[fd].off = openfilelist[fd].length - 1;
        }
    }
    int off = openfilelist[fd].off;
    while(off >= BLOCKSIZE) {
        blockNum = fatPtr->id;
        if(blockNum == END) {
            blockNum = getFreeBLOCK();
            if(blockNum == END) {
                printf("盘块不足\n"); return -1;
            }else {
                fatPtr->id = blockNum;
                fatPtr = (fat*)(myvhard + BLOCKSIZE) + blockNum;
                fatPtr->id = END;
            }
        }
        fatPtr = (fat*)(myvhard + BLOCKSIZE) + blockNum;
        off -= BLOCKSIZE;
    }
    unsigned char *buf = (unsigned char*)malloc(BLOCKSIZE * sizeof(unsigned char));
    unsigned char *blockPtr = (unsigned char *)(myvhard + BLOCKSIZE*blockNum);
    int lenTmp = 0;
    char *textPtr = text;
    while(len > lenTmp) {
        memcpy(buf, blockPtr, BLOCKSIZE);
        for(; off < BLOCKSIZE; ++off) {
            *(buf + off) = *textPtr;
            textPtr ++;
            lenTmp ++;
            if(len == lenTmp) {
                break;
            }
        }
        memcpy(blockPtr, buf, BLOCKSIZE);
        if(off == BLOCKSIZE && len != lenTmp) {
            off = 0;
            blockNum = fatPtr->id;
            if(blockNum == END) {
                blockNum = getFreeBLOCK();
                if(blockNum == END) {
                    printf("盘块用完\n"); return -1;
                }else {
                    blockPtr = (unsigned char *)(myvhard + BLOCKSIZE*blockNum);
                    fatPtr->id = blockNum;
                    fatPtr = (fat *)(myvhard + BLOCKSIZE) + blockNum;
                    fatPtr->id = END;
                }
            }else {
                blockPtr = (unsigned char *)(myvhard + BLOCKSIZE * blockNum);
                fatPtr = (fat *)(myvhard + BLOCKSIZE ) + blockNum;
            }
        }
    }
    openfilelist[fd].off += len;
    if(openfilelist[fd].off > openfilelist[fd].length)
        openfilelist[fd].length = openfilelist[fd].off;
    free(buf);

    memcpy((fat*)(myvhard + BLOCKSIZE*3), (fat*)(myvhard + BLOCKSIZE),sizeof(fcb));
    return len;
}
void Write(int fd) {
    if(fd < 0 || fd >= MAXOPENFILE) {
        printf("文件不存在\n"); return;
    }
    int wstype; printf("输入: 0=截断写, 1=覆盖写, 2=追加写\n");
    scanf("%d",&wstype);
    if(wstype < 0 || wstype > 2) {
        printf("输入超过限制\n"); return;
    }
    char text[MAX_TEXT_SIZE] = "\0";
    char textTmp[MAX_TEXT_SIZE] = "\0";
    printf("请输入文件系统,以end为文件系统\n");
    while(scanf("%s",textTmp)) {
        if(strcmp(textTmp, "end") == 0) {
            break;
        }
        strcat(text, textTmp);
        strcat(text, " ");
    }
    dowrite(fd,text,strlen(text)+1, wstype);
    openfilelist[fd].fcbstate = 1;
}
void Changecurrdlength(char *text) {
    fcb *fcbPtr = (fcb *)text;
    fcbPtr->length = openfilelist[currfd].length;
    openfilelist[currfd].off = 0;
    dowrite(currfd, (char*)fcbPtr, sizeof(fcb), 1);
    openfilelist[currfd].fcbstate = 1;
}
int Close(int fd) {
    if(fd > MAXOPENFILE || fd < 0) {
        printf("不存在这个文件\n"); return -1;
    }
    int fatherFd = find_father_dir(fd);
    if(fatherFd == -1) {
        printf("不存在父目录\n");
        return -1;
    }
    if(openfilelist[fd].fcbstate == 1) {
        char buf[MAX_TEXT_SIZE];
        doread(fatherFd, openfilelist[fatherFd].length, buf);
        fcb* fcbPtr = (fcb *)(buf + sizeof(fcb)*openfilelist[fd].diroff);
        strcpy(fcbPtr->exname, openfilelist[fd].exname);
        strcpy(fcbPtr->filename, openfilelist[fd].filename);
        fcbPtr->first = openfilelist[fd].first;
        fcbPtr->free = openfilelist[fd].free;
        fcbPtr->length = openfilelist[fd].length;
        fcbPtr->time = openfilelist[fd].time;
        fcbPtr->date = openfilelist[fd].date;
        fcbPtr->attribute = openfilelist[fd].attribute;
        openfilelist[fatherFd].off = openfilelist[fd].diroff * sizeof(fcb);
        dowrite(fatherFd, (char *)fcbPtr, sizeof(fcb), 1);
    }
    memset(&openfilelist[fd], 0, sizeof(USEROPEN));
    currfd = fatherFd;
    return currfd;
}
void Remove(char *filename){
    char* fname = strtok(filename, ".");
    char* exname = strtok(NULL, ".");
    if(!exname){
        printf("请输入后缀\n");
        return;
    }
    if(strcmp(exname,"di") == 0){
        printf("不可以输入目录\n");
        return ;
    }

    char buf[MAX_TEXT_SIZE];
    openfilelist[currfd].off = 0;
    doread(currfd,openfilelist[currfd].length,buf);
    int i;
    fcb* fcbPtr = (fcb*)buf;
    for(i=0; i < int(openfilelist[currfd].length / sizeof(fcb)); i++, fcbPtr++){
        if(strcmp(fcbPtr->filename,fname) == 0  && strcmp(fcbPtr->exname,exname) == 0){
            break;
        }
    }
    if( i == int(openfilelist[currfd].length / sizeof(fcb))){
        printf("没有这个文件\n");
        return;
    }

    int blockNum = fcbPtr->first;
    fat* fat1 = (fat*)(myvhard + BLOCKSIZE);
    int next = 0;
    while(1){
        next = fat1[blockNum].id;
        fat1[blockNum].id = FREE;
        if(next != END){
            blockNum = next;
        }
        else{
            break;
        }
    }
    fat1 = (fat*)(myvhard + BLOCKSIZE);
    fat* fat2 = (fat*)(myvhard + BLOCKSIZE*3);
    memcpy(fat2, fat1, sizeof(fat));

    setZero(fcbPtr);

    openfilelist[currfd].off = i * sizeof(fcb);
    dowrite(currfd,(char*)fcbPtr,sizeof(fcb),1);
    Changecurrdlength(buf);
}
void Cd(char *dirname){
    if(openfilelist[currfd].attribute == 1){
        printf("数据文件不能cd");
        return ;
    }else{
        char *buf = (char *)malloc(MAX_TEXT_SIZE);
        openfilelist[currfd].off = 0;
        doread(currfd,openfilelist[currfd].length,buf);
        char tmp[20]; int tot = 0; int fl = 0;
        for(int i = 0; dirname[i]; ++i) {
            if(fl) tmp[tot++] = dirname[i];
            else if(dirname[i] == '/') {
                fl = 1; dirname[i] = 0;
            }
        }
        tmp[tot] = 0;

        int i = 0;
        fcb* fcbPtr = (fcb*)buf;
        for(; i < int(openfilelist[currfd].length / sizeof(fcb)); i++,fcbPtr++){
            if(strcmp(fcbPtr->filename, dirname) == 0 && fcbPtr->attribute == 0){
                break;
            }
        }
        if(strcmp(fcbPtr->exname, "di") != 0){
            printf("不含有非数据文件\n");
            return;
        }else {
            if(strcmp(fcbPtr->filename,".") == 0){
                return;
            } else if(strcmp(fcbPtr->filename, "..") == 0){
                if(currfd == 0){
                    return;
                }else{
                    currfd = Close(currfd);
                    return;
                }
            }
            else{


                int fd = getFreeOpenfilelist();
                if(fd == -1){
                    return;
                }
                else{
                    openfilelist[fd].attribute = fcbPtr->attribute;
                    openfilelist[fd].off = 0;
                    openfilelist[fd].date = fcbPtr->date;
                    openfilelist[fd].time = fcbPtr->time;
                    strcpy(openfilelist[fd].filename, fcbPtr->filename);
                    strcpy(openfilelist[fd].exname,fcbPtr->exname);
                    openfilelist[fd].first = fcbPtr->first;
                    openfilelist[fd].free = fcbPtr->free;

                    openfilelist[fd].fcbstate = 0;
                    openfilelist[fd].length = fcbPtr->length;
                    strcpy(openfilelist[fd].dir,
                    (char*)(string(openfilelist[currfd].dir) + string(dirname) + string("/")).c_str());
                    openfilelist[fd].topenfile = 1;
                    openfilelist[fd].dirno = openfilelist[currfd].first;
                    openfilelist[fd].diroff = i;
                    currfd = fd;
                }
                if(tot) Cd(tmp);
            }
        }
    }
}
void Mkdir(char *dirname) {
    char* fname = strtok(dirname, ".");
    char* exname = strtok(NULL, ".");
    if(exname) {
        printf("不允许输入后缀名\n");
        return;
    }
    char text[MAX_TEXT_SIZE];
    openfilelist[currfd].off = 0;
    int fileLen = doread(currfd, openfilelist[currfd].length, text);
    fcb *fcbPtr = (fcb*)text;
    for(int i = 0; i < (int)(fileLen/sizeof(fcb)); ++i) {
        if(strcmp(dirname, fcbPtr[i].filename) == 0 && fcbPtr->attribute == 0) {
            printf("目录名已经存在!\n"); return;
        }
    }
    int fd = getFreeOpenfilelist();
    if(fd == -1) {
        printf("打开文件表已经被占用\n"); return;
    }
    unsigned short int blockNum = getFreeBLOCK();
    if(blockNum == END) {
        printf("盘块应经被用完\n");
        openfilelist[fd].topenfile = 0; return;
    }
    fat *fat1 = (fat *)(myvhard + BLOCKSIZE);
    fat *fat2 = (fat *)(myvhard + BLOCKSIZE*3);
    fat1[blockNum].id = END;
    fat2[blockNum].id = END;
    int i;
    for(i=0;i < (int)(fileLen/sizeof(fcb)); ++i) {
        if(fcbPtr[i].free == 0) break;
    }
    openfilelist[currfd].off = i*sizeof(fcb);
    openfilelist[currfd].fcbstate = 1;
    fcb* fcbtmp = new fcb;
    fcbtmp->attribute = 0;
    time_t rawtime = time(NULL);
    struct tm* time = localtime(&rawtime);
    fcbtmp->date = (time->tm_year-100)*512 + (time->tm_mon+1)*32 + (time->tm_mday);
    fcbtmp->time = (time->tm_hour)*2048 + (time->tm_min)*32 + (time->tm_sec) / 2;
    strcpy(fcbtmp->filename , dirname);
    strcpy(fcbtmp->exname, "di");
    fcbtmp->first = blockNum;
    fcbtmp->length = 2 * sizeof(fcb);
    fcbtmp->free = 1;
    dowrite(currfd,(char *)fcbtmp,sizeof(fcb),1);
    openfilelist[fd].attribute = 0;
    openfilelist[fd].off = 0;
    openfilelist[fd].date = fcbtmp->date;
    openfilelist[fd].time = fcbtmp->time;
    openfilelist[fd].dirno = openfilelist[currfd].first;
    openfilelist[fd].diroff = i;
    strcpy(openfilelist[fd].exname,"di");
    strcpy(openfilelist[fd].filename,dirname);
    openfilelist[fd].fcbstate = 0;
    openfilelist[fd].first = fcbtmp->first;
    openfilelist[fd].free = fcbtmp->free;
    openfilelist[fd].length = fcbtmp->length;
    openfilelist[fd].topenfile = 1;
    strcpy(openfilelist[fd].dir, (char*)(string(openfilelist[currfd].dir) + string(dirname) + string("/")).c_str());

    strcpy(fcbtmp->filename, ".");
    strcpy(fcbtmp->exname, "di");
    fcbtmp->first = blockNum;
    fcbtmp->length = 2 * sizeof(fcb);
    dowrite(fd,(char*)fcbtmp,sizeof(fcb),1);
    fcb *fcbtmp2 = new fcb;
    memcpy(fcbtmp2,fcbtmp,sizeof(fcb));
    strcpy(fcbtmp2->filename,"..");
    fcbtmp2->first = openfilelist[currfd].first;
    fcbtmp2->length = openfilelist[currfd].length;
    fcbtmp2->date = openfilelist[currfd].date;
    fcbtmp2->time = openfilelist[currfd].time;
    dowrite(fd,(char*)fcbtmp2,sizeof(fcb),1);
    Changecurrdlength(text);
    Close(fd);

}
void Rmdir(char *dirname) {
    char* fname = strtok(dirname, ".");
    char* exname = strtok(NULL, ".");
    if(strcmp(dirname, ".") == 0 || strcmp(dirname, "..") == 0) {
        printf("不能删除特殊目录项\n");
        return ;
    }
    if(exname) {
        printf("删除目录文件 没有后缀名\n"); return;
    }
    char buf[MAX_TEXT_SIZE];
    openfilelist[currfd].off = 0;
    doread(currfd,openfilelist[currfd].length,buf);
    int i;
    fcb* fcbPtr = (fcb*)buf;
    for(i=0; i < int(openfilelist[currfd].length / sizeof(fcb)); i++, fcbPtr++){
        if(strcmp(fcbPtr->filename,fname) == 0  && fcbPtr->attribute == 0){
            break;
        }
    }
    if( i == int(openfilelist[currfd].length / sizeof(fcb))){
        printf("没有这个文件\n");
        return;
    }

    Cd(dirname);
    openfilelist[currfd].off = 0;
    doread(currfd,openfilelist[currfd].length,buf);
    fcbPtr = (fcb*)buf;
    for(i=0; i < int(openfilelist[currfd].length / sizeof(fcb)); i++, fcbPtr++);
    for(fcbPtr--,i--; i >= 0; --i, fcbPtr--){
        if(fcbPtr->attribute == 1){
            char *tmp = fcbPtr->filename; strcat(tmp, "."); strcat(tmp, fcbPtr->exname);
            Remove(tmp);
        }else if(strcmp(fcbPtr->filename,".") == 0 || strcmp(fcbPtr->filename,"..") == 0) continue;
        else {
            char *tmp = fcbPtr->filename;
            Rmdir(tmp);
        }
    }
    Cd("..");

    openfilelist[currfd].off = 0;
    doread(currfd,openfilelist[currfd].length,buf);
    fcbPtr = (fcb*)buf;
    for(i=0; i < int(openfilelist[currfd].length / sizeof(fcb)); i++, fcbPtr++){
        if(strcmp(fcbPtr->filename,fname) == 0  && fcbPtr->attribute == 0){
            break;
        }
    }
    int blockNum = fcbPtr->first;
    fat* fat1 = (fat*)(myvhard + BLOCKSIZE);
    int next = 0;
    while(1) {
        next = fat1[blockNum].id;
        fat1[blockNum].id = FREE;
        if(next != END) {
            blockNum = next;
        }else break;
    }

    fat1 = (fat*)(myvhard + BLOCKSIZE);
    fat* fat2 = (fat*)(myvhard + BLOCKSIZE*3);
    memcpy(fat2, fat1, sizeof(fat));
    setZero(fcbPtr);
    openfilelist[currfd].off = i * sizeof(fcb);
    dowrite(currfd,(char*)fcbPtr,sizeof(fcb),1);
    Changecurrdlength(buf);
}
void Touch(char *filename) {
    char* fname = strtok(filename, ".");
    char* exname = strtok(NULL,".");
    if(strcmp(fname,"") == 0) {
        printf("请输入文件名\n"); return ;
    }
    if(!exname) {
        printf("请输入后缀名\n"); return;
    }
    if(openfilelist[currfd].attribute == 1) {
        printf("数据文件下不允许使用create\n"); return;
    }

    openfilelist[currfd].off = 0;
    char buf[MAX_TEXT_SIZE];
    doread(currfd, openfilelist[currfd].length, buf);
    int i;
    fcb* fcbPtr = (fcb*)(buf);

    for(i=0; i < int(openfilelist[currfd].length / sizeof(fcb)); ++i,++fcbPtr) {
        if(strcmp(fcbPtr->filename,filename)==0 && strcmp(fcbPtr->exname,exname)==0){
            printf("文件已存在\n");
            return;
        }
    }

    fcbPtr = (fcb*)(buf);
    for(i=0; i < int(openfilelist[currfd].length / sizeof(fcb)); ++i,++fcbPtr) {
        if(fcbPtr->free == 0) break;
    }
    int blockNum = getFreeBLOCK();
    if(blockNum == -1){
        printf("没有空闲的盘块号\n");
        return ;
    }
    fat* fat1 = (fat*)(myvhard + BLOCKSIZE);
    fat1[blockNum].id = END;
    fat* fat2 = (fat*)(myvhard + BLOCKSIZE * 3);
    memcmp(fat2, fat1, BLOCKSIZE*2);

    strcpy(fcbPtr->filename,filename);
    strcpy(fcbPtr->exname,exname);
    time_t rawtime = time(NULL);
    struct tm* time = localtime(&rawtime);
    fcbPtr->date = (time->tm_year-100)*512 + (time->tm_mon+1)*32 + (time->tm_mday);
    fcbPtr->time = (time->tm_hour)*2048 + (time->tm_min)*32 + (time->tm_sec) / 2;
    fcbPtr->first = blockNum;
    fcbPtr->free = 1;
    fcbPtr->length = 0;
    fcbPtr->attribute = 1;
    openfilelist[currfd].off = i * sizeof(fcb);
    dowrite(currfd,(char *)fcbPtr,sizeof(fcb),1);

    Changecurrdlength(buf);
}
void Ls(){
   if(openfilelist[currfd].attribute == 1){
        printf("数据文件不能用ls\n");
        return;
    }
    char buf[MAX_TEXT_SIZE];

    openfilelist[currfd].off = 0;
    doread(currfd, openfilelist[currfd].length, buf);
    fcb* fcbPtr = (fcb*)buf;
    for(int i=0; i < (int)(openfilelist[currfd].length / sizeof(fcb)); i++){
        if(fcbPtr->free == 1){
            if(fcbPtr->attribute == 0){
                printf("%s\\\t<DIR>\t%d/%d/%d\t%d:%d:%d\n",
                       fcbPtr->filename,
                       (fcbPtr->date>>9)+2000,
                       (fcbPtr->date>>5)&0x000f,
                       (fcbPtr->date)&0x001f,
                       (fcbPtr->time>>11),
                       (fcbPtr->time>>5)&0x003f,
                       (fcbPtr->time)&0x001f * 2);
            }
            else{
                unsigned int length = fcbPtr->length;
                if(length != 0)
                    length -= 2;
                printf("%s.%s\t%dB\t%d/%d/%d\t%02d:%02d:%02d\n",
                       fcbPtr->filename,
                       fcbPtr->exname,
                       length,
                       (fcbPtr->date>>9)+2000,
                       (fcbPtr->date>>5)&0x000f,
                       (fcbPtr->date)&0x001f,
                       (fcbPtr->time>>11),
                       (fcbPtr->time>>5)&0x003f,
                       (fcbPtr->time)&0x001f * 2);
            }
        }
        fcbPtr++;
    }
}
void Open(char *filename){
    char buf[MAX_TEXT_SIZE];
    openfilelist[currfd].off = 0;
    doread(currfd, openfilelist[currfd].length, buf);
    char *fname = strtok(filename,".");
    char *exname = strtok(NULL, ".");
    if(!exname){
        printf("请输入后缀名\n");
        return ;
    }
    int i;
    fcb* fcbPtr = (fcb*)buf;
    for(i=0; i < int(openfilelist[currfd].length / sizeof(fcb)); i++, fcbPtr++){
        if(strcmp(fcbPtr->filename,fname) == 0 && strcmp(fcbPtr->exname,exname) == 0 && fcbPtr->attribute == 1){
            break;
        }
    }
    if(i == int(openfilelist[currfd].length / sizeof(fcb))){
        printf("不存在此文件\n");
        return ;
    }
    int fd = getFreeOpenfilelist();
    if(fd == -1){
        printf("文件打开已满\n");
        return ;
    }
    openfilelist[fd].attribute = 1;
    openfilelist[fd].off = 0;
    openfilelist[fd].date = fcbPtr->date;
    openfilelist[fd].time = fcbPtr->time;
    strcpy(openfilelist[fd].exname, exname);
    strcpy(openfilelist[fd].filename,fname);
    openfilelist[fd].length = fcbPtr->length;
    openfilelist[fd].first = fcbPtr->first;
    strcpy(openfilelist[fd].dir,(string(openfilelist[currfd].dir) + string(filename)).c_str());
    openfilelist[fd].dirno = openfilelist[currfd].first;
    openfilelist[fd].diroff = i;
    openfilelist[fd].free = 1;
    openfilelist[fd].topenfile = 1;
    openfilelist[fd].fcbstate = 0;
    currfd = fd;
}
void Exit() {
    while(currfd) {
        Close(currfd);
    }
    FILE *fp = fopen(FileName,"w");
    fwrite(myvhard, SIZE, 1, fp);
    fclose(fp);
}

int main() {
    char cmd[][10] = {"mkdir", "rmdir", "ls", "cd", "touch", "rm", "open", "close", "write", "read", "exit"};
    printf("*************欢迎使用 basasuya文件操作系统**************\n");
    startSys();
    while(1) {
        printf("%s>",openfilelist[currfd].dir);
        char s[20];
        scanf("%s",s);
        int i;
        for(i = 0; i < 12; ++i) {
            if(strcmp(s, cmd[i]) == 0) break;
        }
        if(i == 0) {
            scanf("%s",s); Mkdir(s);
        }else if(i == 1) {
            scanf("%s",s); Rmdir(s);
        }else if(i == 2) {
            Ls();
        }else if(i == 3) {
            scanf("%s",s); Cd(s);
        }else if(i == 4) {
            scanf("%s",s); Touch(s);
        }else if(i == 5) {
            scanf("%s",s); Remove(s);
        }else if(i == 6) {
            scanf("%s",s); Open(s);
        }else if(i == 7) {
            Close(currfd);
        }else if(i == 8) {
            Write(currfd);
        }else if(i == 9) {
            Read(currfd);
        }else if(i == 10) {
            Exit();
            printf("退出文件系统\n"); break;
        }else printf("命令不合法\n");
    }
    return 0;
}

转载于:https://www.cnblogs.com/Basasuya/p/8433721.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值