Linux二级文件系统(未完成版本)

时间:2022-05-23 09:02:36
#include<stdio.h>
#include<process.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define MAX_FILE_NAME_SIZE 10        /****    最长文件名   ******/
#define FILE_MAX_BLOCK_NUM 2        /*****   文件所占最多的磁盘块数    ****/
#define USERNAME_MAX_SIZE  10      /*   最长用户名字符个数  */
#define DINODE_SIZE 50             /*   磁盘inode节点字节数   */
#define BLOCK_SIZE  512            /*   磁盘块大小   */
#define BLOCK_TOTAL  100           /*   磁盘块总数   */
#define RELOGINTIME  3             /*   定义用户可以重复登录的次数   */
 
/*****    数据结构定义    *****/
struct Superblock{                               /*超级块*/
        short int fistack[40];                 /* 空闲节点号栈 */
        short int fiptr;                       /* 空闲节点栈指针 */
        short int fbstack[100];                /* 空闲盘块号栈 */
        short int fbptr;                       /* 空闲盘块栈指针 */
        short int inum;                        /* 空闲节点总数 */
        short int bnum;                        /* 空闲盘块总数 */
        short int inodeNum;                    /* i节点块块数 */
        short int blockNum;                    /* 数据块块数 */
        char s_fmod;                           /* 超级块是否修改的标志 */
        short int  inode_bitmap[40];           /* inode节点位视图 */
        short int  block_bitmap[100];          /* 数据块位视图 */
}super_Block;



struct Dir_entry{                             /*目录项*/
    char file_name[MAX_FILE_NAME_SIZE];       /* 文件名 */
    short int inode_number;                   /* 磁盘inode节点编号 */
}dir_entry[5];


struct Dinode{                                 /*磁盘inode节点*/
    char user_name[USERNAME_MAX_SIZE];       /* 所属用户 */
    short int di_number;                     /* 关联文件数 */
    char i_mode[11];                         /* 存取权限 第一个字符代表文件类型,第2到11个字符代表本用户的权限和其他用户的权限,
                                                    /*包括读,写,可执行,创建和删除5种权限 */
    short int file_size;                     /* 文件大小 */
    int di_addr[FILE_MAX_BLOCK_NUM];         /* 物理盘块号 */
}dinode[6];




struct Inode{                                /*内存inode节点*/
        struct Inode *i_forw;                /*前一个inode节点*/
        struct Inode *i_back;                /*后一个inode节点*/
        char i_flag;                         /*inode是否被修改的标志*/
        int i_into;                          /*磁盘inode编号*/
        int i_count;                         /*引用计数*/
        short int file_size;                 /* 文件大小 */
        short int di_number;                 /*关联文件数,当为0时,删除该文件*/
        char i_mode[11];                     /*存取权限 第一个字符代表文件类型,第2到11个字符代表本用户的权限和其他用户的权限,
                                                    包括读,写,可执行,创建和删除5种权限,1代表允许,0代表拒绝 */
        char user_name[USERNAME_MAX_SIZE];   /* 所属用户 */
        int di_addr[FILE_MAX_BLOCK_NUM];     /* 物理盘块号 */
}currentUserdirInode,*inodeListHead,*inodeListTail;



struct Uid{                                  //用户标识
        char user_name[USERNAME_MAX_SIZE];       /*登录密码*/
}uid;


struct User_open_table{                      //用户打开表
        char user_name[USERNAME_MAX_SIZE];   /*用户名*/
        char *openFileNames[46];             /*用户打开文件的名称列表*/
        int open_file_num;                   /*用户打开的文件数目*/
}currentUser_open_table;

//磁盘文件指针
FILE *disk_Pointer;
//当前目录
char *current_dir = "ROOT";
char realName[10];




//测试函数: 打印超级块
void showSuperBlock(){
    int i = 0;
    printf("空闲节点栈指针为: %d\n", super_Block.fiptr);
    printf("空闲盘块号栈如下所示: \n");
    for(i = 0; i <= 99; i++){
        printf("第%d号块使用情况: %d\n",i,super_Block.fbstack[i]);
    }
    printf("空闲盘块栈指针: %d\n",super_Block.fbptr);
    printf("空闲节点总数: %d\n",super_Block.inum);
    printf("空闲盘块总数: %d\n",super_Block.bnum);
    printf("i节点块数: %d\n",super_Block.inodeNum);
    printf("数据块块数: %d\n",super_Block.blockNum);
    printf("超级块是否被修改: %c\n",super_Block.s_fmod);
    printf("inode节点位视图如下: \n");
    for(i = 0; i <= 39; i++){
        printf("第%d位的值为: %d\n",i,super_Block.inode_bitmap[i]);
    }
    printf("数据块位视图如下: \n");
    for(i = 0; i <= 39; i++){
        printf("第%d位的值为: %d\n",i,super_Block.block_bitmap[i]);
    }
}


//测试函数: 打印当前用户子目录inode节点
void showCurrentUserDirInode(){
    int i = 0;
    printf("前一个inode节点的内存地址: %d\n",currentUserdirInode.i_forw);
    printf("后一个inode节点的内存地址: %d\n",currentUserdirInode.i_back);
    printf("inode是否被修改: %c\n",    currentUserdirInode.i_flag);
    printf("磁盘inode编号: %d\n",currentUserdirInode.i_into);
    printf("引用计数为: %d\n",currentUserdirInode.i_count);
    printf("文件大小为: %d\n",currentUserdirInode.file_size);
    printf("关联文件数目为: %d\n",currentUserdirInode.di_number);
    printf("文件权限如下所示: \n");
    for(i = 0; i <= 10; i++){
        printf("第%d位的值为: %c\n",i,currentUserdirInode.i_mode[i]);
    }
    printf("所属用户为: \n");
    puts(currentUserdirInode.user_name);
    printf("物理盘块号如下所示: \n");
    for(i = 0; i <= FILE_MAX_BLOCK_NUM - 1; i++){
        printf("第%d位的值为: %d\n",i,currentUserdirInode.di_addr[i]);
    }
}


//测试函数: 打印用户打开表
void showUserOpenTable(){
    int i = 0;
    printf("当前用户为: \n");
    puts(currentUser_open_table.user_name);
    printf("文件总数为: %d\n",currentUser_open_table.open_file_num);
    printf("该用户打开的文件列表如下: \n");
    for(i = 0; i <= 45; i++){
        printf("第%d个文件是: \n");
        puts(currentUser_open_table.openFileNames[i]);
    }
}


//显示文件系统提示信息
void showInfo(char *info)
{
    printf("%s\n",info);
}


//在当前用户目录下面查询文件名对应的文件是否存在,若存在,返回文件对应的磁盘inode磁盘节点编号,以0为基准,否则返回-1
int searchFileFromCurrentUserDir(char *filename){
    //接收从磁盘读取的文件名
    char file_name[10];
    //待校验的文件名的代理
    char filenameProxy[10];
    //接收从磁盘读取的用户名
    char user_name[10];
    //文件inode磁盘编号
    int inode_number = -1;
    //记录文件指针的偏移量
    int offset = 0;
    //待校验的文件名的长度
    int fileRealLength = strlen(filename);
    int i = 0;
    fseek(disk_Pointer,(3584+65),0);

    //初始化输入的文件名
    strcpy(filenameProxy,filename);
    for(i = 0; i <= 9; i++){
        if(i >= fileRealLength){
            filenameProxy[i] = ' ';
        }
    }
    filenameProxy[MAX_FILE_NAME_SIZE] = '\0';


    while(offset <= 520){
        for(i = 0; i <= (MAX_FILE_NAME_SIZE - 1); i++){
            fscanf(disk_Pointer,"%c",&file_name[i]);
        }
        file_name[MAX_FILE_NAME_SIZE] = '\0';
        if(strcmp(filenameProxy,file_name) == 0){
            //判断该文件的所属用户
            fseek(disk_Pointer,1L,1);
            fscanf(disk_Pointer,"%d",&inode_number);
            fseek(disk_Pointer,(1024 + inode_number * 50),0);
            for(i = 0; i <= (MAX_FILE_NAME_SIZE - 1); i++){
                fscanf(disk_Pointer,"%c",&user_name[i]);
            }
            user_name[MAX_FILE_NAME_SIZE] = '\0';
            if(strcmp(user_name,currentUserdirInode.user_name) == 0){
                break;
            }else{
                inode_number = -1;
                offset = offset + 13;
            }
        }else{
            offset = offset + 13;
        }
        fseek(disk_Pointer,(3584 + 65 + offset),0);
    }
    return inode_number;
}


//磁盘块分配函数,返回空闲数据盘块号
int balloc(void)
{
    int j = 0;
    //申请的起始物理盘块号
    int blackNum = -1;
    for(j = 9; j <= 99; j++){
        if(super_Block.block_bitmap[j] == 0){
            blackNum = j;
            //修改超级块中的物理盘块号位视图
            super_Block.block_bitmap[j] = 1;
            super_Block.block_bitmap[j + 1] = 1;
            super_Block.s_fmod = 'y';
            break;
        }
    }
    printf("执行完balloc函数!\n");
    return blackNum;
}



//写超级块
void writeSuperBlock(int flag){
    int i = 0;
    for(i = 0; i <= 39; i++){
        //将超级块中的空闲节点号栈写入磁盘文件
        fprintf(disk_Pointer,"%d ",super_Block.fistack[i]);
    }
    //将空闲节点栈指针写入磁盘文件
    fprintf(disk_Pointer,"%d ",super_Block.fiptr);
    //将空闲盘块号栈写入磁盘文件
    for(i = 0; i <= 99; i++){
        //1到9号磁盘块已经被占用
        if(i <= 8){
            fprintf(disk_Pointer,"%d ",1);
        }else{
            fprintf(disk_Pointer,"%d ",super_Block.fbstack[i]);
        }
    }
    //将空闲盘块栈指针写入磁盘文件
    fprintf(disk_Pointer,"%d ",super_Block.fbptr);
    //将空闲节点总数写入磁盘文件
    if(flag == 1){
        super_Block.inum = 40;
    }
    fprintf(disk_Pointer,"%d ",super_Block.inum);
    //将空闲盘块总数写入文件
    if(flag == 1){
        super_Block.bnum = 91;
    }
    fprintf(disk_Pointer,"%d ",super_Block.bnum);
    //将i节点块数写入磁盘文件
    super_Block.inodeNum = 4;
    fprintf(disk_Pointer,"%d ",super_Block.inodeNum);
    //将数据块块数写入文件
    super_Block.blockNum = 91;
    fprintf(disk_Pointer,"%d ",super_Block.blockNum);
    //将超级块修改标志写入磁盘文件
    super_Block.s_fmod = 'n';
    fprintf(disk_Pointer,"%c ",super_Block.s_fmod);
    //将i节点位视图写入文件
    for(i = 0; i <= 39; i++){
        fprintf(disk_Pointer,"%d ",super_Block.inode_bitmap[i]);
    }
    //将数据块位视图写入文件
    for(i = 0; i <= 99; i++){
        //1到9号磁盘块已经被占用
        if(i <= 8){
            fprintf(disk_Pointer,"%d ",1);
        }else{
            fprintf(disk_Pointer,"%d ",super_Block.block_bitmap[i]);
        }
    }
}



// 磁盘inode节点内容获取函数,index为磁盘文件的inode节点编号
void iget(int index, Inode *inode)
{
    int i = 0;
    fseek(disk_Pointer,1536 + index * 50,0);
    for(i = 0; i <= (MAX_FILE_NAME_SIZE - 1); i++){
        fscanf(disk_Pointer,"%c",&(inode->user_name[i]));
    }
    fseek(disk_Pointer,1L,1);
    fscanf(disk_Pointer,"%d",&(inode->di_number));
    for(i = 0; i <= 10; i++){
        fscanf(disk_Pointer,"%c",&(inode->i_mode[i]));
    }
    fseek(disk_Pointer,1L,1);
    fscanf(disk_Pointer,"%d",&(inode->file_size));
    for(i = 0 ; i <= (FILE_MAX_BLOCK_NUM - 1); i++){
        fscanf(disk_Pointer,"%d",&(inode->di_addr[i]));
    }
    inode->i_flag = 'n';
    inode->i_into = index;
    inode->i_count = 1;
}



// index为磁盘索引节点号, 磁盘inode节点写回函数
void iset(int index, Inode *inode)
{
    int i = 0;
    fseek(disk_Pointer, (1536 + index * 50) , 0);
    printf("inode起始地址为: %d\n",(1536 + index * 50));

    for(i = 0; i <= (MAX_FILE_NAME_SIZE - 1); i++){
        fprintf(disk_Pointer,"%c",inode->user_name[i]);
    }
    fprintf(disk_Pointer," %d ",inode->di_number);
    for(i = 0; i <= 10; i++){
        fprintf(disk_Pointer,"%c ",inode->i_mode[i]);
    }
    fprintf(disk_Pointer,"%d ",inode->file_size);
    fprintf(disk_Pointer,"%d ",inode->di_addr[0]);
    fprintf(disk_Pointer,"%d ",inode->di_addr[1]);
}


//查找index索引号对应的内存inode节点,返回inode节点指针
Inode* findInodeFromInodeList(int index){
    Inode *currentInodePointer = NULL;
    currentInodePointer = inodeListHead;
    while(index > 0 && inodeListHead != NULL){
        currentInodePointer = currentInodePointer->i_back;
        index--;
    }
    return currentInodePointer;
}


//删除内存inode节点
void deleteInode(Inode *targetInodePointer){
    if(targetInodePointer->i_back == NULL && targetInodePointer->i_forw != NULL){
        inodeListTail = targetInodePointer->i_forw;
        (targetInodePointer->i_forw)->i_back = NULL;
        free(targetInodePointer);
    }else if(targetInodePointer->i_forw == NULL && targetInodePointer->i_back != NULL){
        inodeListHead = targetInodePointer->i_back;
        inodeListHead->i_forw = NULL;
        targetInodePointer->i_back = NULL;
        free(targetInodePointer);
    }else if(targetInodePointer->i_forw == NULL && targetInodePointer->i_back == NULL){
        inodeListHead = NULL;
        inodeListTail = NULL;
        free(targetInodePointer);
    }else if(targetInodePointer->i_forw != NULL && targetInodePointer->i_back != NULL){
        (targetInodePointer->i_forw)->i_back = targetInodePointer->i_back;
        (targetInodePointer->i_back)->i_forw = targetInodePointer->i_forw;
        targetInodePointer->i_back = NULL;
        targetInodePointer->i_forw = NULL;
        free(targetInodePointer);
    }
}


//向inode节点链表中插入一个节点
void insertInode(Inode *targetInodePointer, Inode *currentInode, char *filename){
    int i = 0;
    //inode节点链表和用户打开表中的文件名链表一一对应
    int index = 0;
    for(i = 0; i <= 45; i++){
        printf("+++++%d\n",strlen(currentUser_open_table.openFileNames[i]));
        if((strcmp(currentUser_open_table.openFileNames[i],"          ") == 0)){
            printf("enter 1.........\n");
            strcpy(currentUser_open_table.openFileNames[i],filename);
            if(i != 0 && strlen(currentUser_open_table.openFileNames[i+1]) != 0){
                targetInodePointer = findInodeFromInodeList(index);
                if(targetInodePointer == NULL){
                    //插入到链表最后一个节点后面
                    currentInode->i_forw = inodeListTail;
                    currentInode->i_back = NULL;
                    inodeListTail->i_back = currentInode;
                    inodeListTail = currentInode;
                }else //if(strcpy(currentUser_open_table.openFileNames[i+1],"          ") != 0)
                {
                    //插入的位置在targetInodePointer指向的节点的前面
                    currentInode->i_back = targetInodePointer;
                    currentInode->i_forw = targetInodePointer->i_forw;
                    (targetInodePointer->i_forw)->i_back = currentInode;
                    targetInodePointer->i_forw = currentInode;
                }
                
            }else if(i != 0 && (strlen(currentUser_open_table.openFileNames[i+1]) == 0)){
                //插入链表的最后一个节点后面
                currentInode->i_forw = inodeListTail;
                currentInode->i_back = NULL;
                inodeListTail->i_back = currentInode;
                inodeListTail = currentInode;
            }else if(i == 0){
                //targetInodePointer = findInodeFromInodeList(index);
                if(inodeListHead == NULL){
                    //链表中的第一个节点
                    inodeListTail = currentInode;
                    inodeListHead = currentInode;
                    currentInode->i_forw = NULL;
                    currentInode->i_back = NULL;
                }else{
                    //插入链表中首节点的前面
                    currentInode->i_back = inodeListHead;
                    currentInode->i_forw = NULL;
                    inodeListHead->i_forw = currentInode;
                    inodeListHead = currentInode;
                }
            }
            break;
        }else if(strlen(currentUser_open_table.openFileNames[i]) == 1){
            printf("enter 2............\n");
            strcpy(currentUser_open_table.openFileNames[i],filename);
            if(i == 0){
                //链表长度为0, 这是第一个创建的文件
                inodeListTail = currentInode;
                inodeListHead = currentInode;
                currentInode->i_forw = NULL;
                currentInode->i_back = NULL;
            }else{
                //插入链表的最后
                currentInode->i_forw = inodeListTail;
                currentInode->i_back = NULL;
                inodeListTail->i_back = currentInode;
                inodeListTail = currentInode;
            }
            break;
        }else{
            index++;
        }
    }
}



// 磁盘inode节点释放函数
void ifree(int index)
{
    printf("inode被清空之前: \n");
    int i = 0;
    fseek(disk_Pointer,1536 + index * 50,0);
    for(i = 0; i <= 49; i++){
        fprintf(disk_Pointer,"%c",' ');
    }
    printf("inode被清空之后: \n");
}


// 申请磁盘inode节点函数,返回申请的磁盘inode节点编号
int ialloc()
{
    int i = 0;
    //为该文件申请的磁盘inode节点编号
    int inodeNum = -1;
    //读取超级块中的inode节点视图
    for(i = 0; i <= 39; i++){
        if(super_Block.inode_bitmap[i] == 0){
            inodeNum = i;    
            break;
        }
    }
    printf("执行完ialloc函数!\n");
    return inodeNum;
}


//磁盘块释放函数
void bfree(int start_index, int file_size)
{
    printf("数据块被清空之前: \n");
    printf("start_index的值为: %d\n",start_index);
    printf("file_size的值为: %d\n",file_size);
    int i = 0;
    fseek(disk_Pointer,start_index,0);
    for(i = 0; i < file_size; i++){
        fprintf(disk_Pointer,"%c",' ');
    }
    fflush(disk_Pointer);
    printf("数据块被清空之后: \n");
}


//访问控制函数, powerType取值范围为0~10
bool access(Inode *inode, char *username, int powerType)
{
    printf("出现异常之前!\n");
    bool havePower = false;
    if(strcmp(inode->user_name,username) == 0){
        printf("允许1!\n");
        //双层权限检验,第一层为当前目录,第二层为当前文件inode节点
        if((currentUserdirInode.i_mode[powerType] == '1') && (inode->i_mode[powerType] == '1')){
            printf("允许2!\n");
            havePower = true;
        }
    }
    printf("出现异常之后!\n");
    return havePower;
}


//打开文件函数
bool openFile(char *fileName)
{
    bool flag = false;
    int i = 0;
    
    if(strlen(fileName) > MAX_FILE_NAME_SIZE){
        flag = false;
        return flag;
    }
    for(i = 0; i <= 45; i++){
        if(strcmp(fileName,currentUser_open_table.openFileNames[i]) == 0){
            flag = true;
            break;
        }
    }

    if(flag == true){
        return flag;
    }else{
        //检查目录项中是否有该文件名对应的文件
        int inodeNum = searchFileFromCurrentUserDir(fileName);
        if(inodeNum == -1){
            flag = false;
        }else{
            //将该文件的磁盘inode节点加载到内存中
            Inode *currentInode = NULL;
            currentInode = (Inode *)malloc(sizeof(Inode));
            //初始化inode节点
            iget(inodeNum,currentInode);
            //引用计数加1
            currentInode->i_count++;
            currentInode->i_flag = 'y';
            
            Inode *targetInodePointer = NULL;
            //插入inode节点
            if(inodeListHead == NULL){
                inodeListHead = currentInode;
                inodeListTail = currentInode;
                strcpy(currentUser_open_table.openFileNames[0],fileName);
            }else{
                insertInode(targetInodePointer,currentInode,fileName);
            }
            currentUser_open_table.open_file_num++;
            flag = true;
        }
        return flag;
    }
}


//创建文件函数
bool createFile(char *filename, char *content)
{
    if(strlen(filename) > MAX_FILE_NAME_SIZE){
        printf("文件名长度为: %d\n",strlen(filename));
        printf("文件名不能超过10个字符,请核对后再次输入!\n");
        return false;
    }else if(strlen(content) > FILE_MAX_BLOCK_NUM * 512){
        printf("文件内容过长, 请重新输入!\n");
        return false;
    }else if(searchFileFromCurrentUserDir(filename) != -1){
        printf("存在重名文件, 请重新输入!\n");
        return false;
    }else if(access(&currentUserdirInode, currentUserdirInode.user_name,4) == false){
        showCurrentUserDirInode();
        printf("对不起,您没有在当前目录下创建文件的权限!\n");
        return false;
    }else if(currentUserdirInode.di_number > 9){
        printf("当前目录下的文件数目已达到极限!\n");
        return false;
    }else{
        int i = 0;
        //为该文件申请的磁盘数据盘块号
        int blockNum = -1;
        //为该文件申请的磁盘inode节点编号
        int inodeNum = -1;
        //当前内存中的磁盘inode节点
        struct Inode *currentInode = NULL;
        Inode *targetInodePointer = NULL;
        inodeNum = ialloc();
        if(inodeNum != -1){
            blockNum = balloc();
            if(blockNum != -1){
                currentInode = (Inode *)malloc(sizeof(Inode));
                //初始化currentInode并将其链接到内存inode节点链表中
                currentInode->i_forw = NULL;
                currentInode->i_back = NULL;
                currentInode->i_flag = 'y';
                currentInode->i_into = inodeNum;
                currentInode->i_count = 1;
                currentInode->file_size = strlen(content);
                currentInode->di_number = 1;
                currentInode->i_mode[0] = '1';
                currentInode->i_mode[1] = '1';
                currentInode->i_mode[2] = '1';
                currentInode->i_mode[3] = '0';
                currentInode->i_mode[4] = '1';
                currentInode->i_mode[5] = '1';
                currentInode->i_mode[6] = '1';
                currentInode->i_mode[7] = '0';
                currentInode->i_mode[8] = '0';
                currentInode->i_mode[9] = '0';
                currentInode->i_mode[10] = '0';
                strcpy(currentInode->user_name,currentUserdirInode.user_name);
                currentInode->di_addr[0] = 512 * 9 + 512 * inodeNum;
                currentInode->di_addr[1] = 512 * 9 + 512 * (inodeNum + 1);
                //将新创建的文件的inode节点写到磁盘中
                iset(currentInode->i_into,currentInode);

                //修改用户打开表
                currentUser_open_table.open_file_num = currentUser_open_table.open_file_num + 1;

                //判断链表是否为空
                if(inodeListHead == NULL){
                    inodeListHead = currentInode;
                    inodeListTail = currentInode;
                    //将文件名加入用户打开表中
                    strcpy(currentUser_open_table.openFileNames[0],filename);
                }else{
                    printf("插入inode节点之前.....\n");
                    insertInode(targetInodePointer,currentInode,filename);
                    printf("插入inode节点之后.....\n");
                }

                //将文件内容写入对应磁盘块中
                fseek(disk_Pointer,currentInode->di_addr[0],0);
                printf("地址为.......%d\n",currentInode->di_addr[0]);
                fputs(content,disk_Pointer);

                //申请目录项
                fseek(disk_Pointer,(3584 + 5 * 13 + currentInode->i_into * 13),0);
                int fileNameLength = strlen(filename);
                for(i = 0; i <= (MAX_FILE_NAME_SIZE - 1); i++){
                    if((i + 1) <= fileNameLength){
                        fprintf(disk_Pointer,"%c",filename[i]);
                    }else{
                        fprintf(disk_Pointer,"%c",' ');
                    }
                }
                fprintf(disk_Pointer," %d ",currentInode->i_into);
                fflush(disk_Pointer);

                //修改当前用户子目录inode节点
                (currentUserdirInode.di_number)++;
                currentUserdirInode.file_size = currentUserdirInode.file_size + strlen(content);
                currentUserdirInode.i_flag = 'y';

                //修改超级块
                super_Block.fistack[inodeNum] = 1;
                super_Block.fiptr = super_Block.fiptr + 1;
                super_Block.fbstack[blockNum] = 1;
                super_Block.fbstack[blockNum+1] = 1;
                super_Block.fbptr = super_Block.fbptr + 2;
                super_Block.inum = super_Block.inum - 1;
                super_Block.bnum = super_Block.bnum - 2;
                super_Block.s_fmod = 'y';
                //修改超级块中的磁盘inode节点位视图
                super_Block.inode_bitmap[inodeNum] = 1;
                //修改超级块中的物理盘块号位视图
                super_Block.block_bitmap[blockNum] = 1;
                super_Block.block_bitmap[blockNum+1] = 1;
                printf("创建文件成功!\n");
                return true;
            }else{
                printf("创建文件失败, 无可用磁盘数据盘块!\n");
                return false;
            }
        }else{
            printf("创建文件失败, 无可用磁盘inode节点!\n");
            return false;
        }
    }
}


//从当前目录下查找文件名对应的文件inode节点, 若有, 返回文件名对应的内存inode节点指针; 若没有,返回空指针
Inode* searchFileNameFromUserOpenTable(char *filename){
    Inode *targetInode = NULL;
    int index = -1;
    if(inodeListHead == NULL){
        //还未创建过任何文件或磁盘中已经没有任何文件
        return NULL;
    }
    for(int i = 0; i <= 45; i++){
        if(strlen(currentUser_open_table.openFileNames[i]) > 0 && (strcmp(currentUser_open_table.openFileNames[i],"          ") != 0)){
            index++;
        }
        if(strcmp(filename,currentUser_open_table.openFileNames[i]) == 0){  
            //遍历内存inode节点链表,查找对应filename的inode节点
            printf("出现异常之前!\n");
            targetInode = findInodeFromInodeList(index);
            printf("出现异常值之后!\n");
            break;
        }
    }
    return targetInode;
}


//读文件函数
void readFile(char *fileName)
{
    Inode *targetInode = NULL;
    Inode *targetInodePointer = NULL;
    int inodeNumber = -1;
    int fileSize = 0;
    //每次最多读出的字符个数
    char str[1024];

    if(strlen(fileName) > MAX_FILE_NAME_SIZE){
        printf("文件名字过长,请核对后再输入!\n");
        return;
    }else if(currentUserdirInode.i_mode[1] == 0){
        printf("对不起, 您没有读取该文件的权限!\n");
        return;
    }
    targetInode = searchFileNameFromUserOpenTable(fileName);
    if(targetInode == NULL){
        inodeNumber = searchFileFromCurrentUserDir(fileName);
        if(inodeNumber == -1){
            printf("目标文件不存在!\n");
            return;
        }else{
            targetInode = (Inode *)malloc(sizeof(Inode));
            iget(inodeNumber,targetInode);

            //将inode链接到内存inode链表中
            insertInode(targetInodePointer,targetInode,fileName);
            //修改用户打开表
            currentUser_open_table.open_file_num = currentUser_open_table.open_file_num + 1;

            //根据inode读取文件内容
            fileSize = targetInode->file_size;
            fseek(disk_Pointer,targetInode->di_addr[0],0);
            while((ftell(disk_Pointer) - targetInode->di_addr[0]) <= fileSize){
                fgets(str,sizeof(str),disk_Pointer);
                printf("%s\n",str);
            }
        }
    }else{
        iget(inodeNumber,targetInode);
        fileSize = targetInode->file_size;
        fseek(disk_Pointer,targetInode->di_addr[0],0);
        while((ftell(disk_Pointer) - targetInode->di_addr[0]) <= fileSize){
            fgets(str,strlen(str),disk_Pointer);
            printf("%s\n",str);
        }
    }
}


//写文件函数
void writeFile(char *fileName)
{
    Inode *targetInode = NULL;
    int inodeNumber = -1;
    int fileSize = 0;
    char *str = NULL;

    if(strlen(fileName) > MAX_FILE_NAME_SIZE){
        printf("文件名字过长,请核对后再输入!\n");
        return;
    }else if(currentUserdirInode.i_mode[2] == 0){
        printf("对不起, 您没有向该文件写入内容的权限!\n");
        return;
    }

    targetInode = searchFileNameFromUserOpenTable(fileName);
    if(targetInode == NULL){
        printf("文件未打开!\n");
        return;
    }else{
        targetInode = (Inode *)malloc(sizeof(Inode));
        iget(inodeNumber,targetInode);
        fileSize = targetInode->file_size;
        fseek(disk_Pointer,targetInode->di_addr[0],0);
        if(fileSize >= FILE_MAX_BLOCK_NUM * 1024){
            printf("文件长度已到达最大, 无法继续写入!\n");
            return;
        }else{
            //写入文件内容
            printf("请输入要写入的文件内容: \n");
            getchar();
            gets(str);
            if(strlen(str) > (FILE_MAX_BLOCK_NUM * 1024 - fileSize)){
                printf("文件内容过长, 拒绝写入!\n");
                return;
            }else{
                fputs(str,disk_Pointer);
                //改变inode中的文件长度字段
                targetInode->file_size = targetInode->file_size + strlen(str);
                targetInode->i_flag = 'y';
                //修改当前用户子目录
                currentUserdirInode.file_size = currentUserdirInode.file_size + strlen(str);
                currentUserdirInode.i_flag = 'y';
            }
        }
    }
}


//删除文件函数
bool deleteFile(char *filename)
{
    Inode *targetInodePointer = NULL;
    int i = 0;
    printf("出现异常之前!\n");
    if(strlen(filename) > MAX_FILE_NAME_SIZE){
        printf("出现异常之后!\n");
        printf("文件名不能超过10个字符,请核对后再次输入!\n");
        return false;
    }else if(access(&currentUserdirInode, currentUserdirInode.user_name,5) == false){
        printf("对不起, 您没有删除文件的权限!\n");
        return false;
    }

    //从当前目录下查找文件名对应的文件inode节点
    targetInodePointer = searchFileNameFromUserOpenTable(filename);
    if(targetInodePointer != NULL)
    {
        printf("在内存中.....\n");
        //修改超级块
        super_Block.fistack[targetInodePointer->i_into] = 0;
        super_Block.fbstack[(targetInodePointer->di_addr[0])/512] = 0;
        super_Block.fbstack[(targetInodePointer->di_addr[0])/512+1] = 0;
        super_Block.inum++;
        super_Block.bnum++;
        super_Block.s_fmod = 'y';
        super_Block.inode_bitmap[targetInodePointer->i_into] = 0;
        super_Block.block_bitmap[(targetInodePointer->di_addr[0])/512] = 0;
        super_Block.block_bitmap[(targetInodePointer->di_addr[0])/512+1] = 0;
        //修改当前用户子目录inode节点
        currentUserdirInode.di_number--;
        currentUserdirInode.file_size = currentUserdirInode.file_size - targetInodePointer->file_size;
        currentUserdirInode.i_flag = 'y';

        //清空目录项
        fseek(disk_Pointer,3584 + 65,0);
        char currentFileName[10];
        char filenameProxy[10];
        strcpy(filenameProxy,filename);

        int fileRealLength = strlen(filename);
        for(i = 0; i < 40; i++){
            int j = 0;
            for(j = 0; j <= 9; j++){
                fscanf(disk_Pointer,"%c",&currentFileName[j]);
            }
            currentFileName[MAX_FILE_NAME_SIZE] = '\0';

            //寻找插入'\0'的合适位置
            for(j = 0; j <= 9; j++){
                if(j >= fileRealLength){
                    filenameProxy[j] = ' ';
                }
            }
            filenameProxy[MAX_FILE_NAME_SIZE] = '\0';
            
            if(strcmp(filenameProxy,currentFileName) == 0){
                fseek(disk_Pointer,-10L,1);
                for(j = 0; j <= 12; j++){
                    fprintf(disk_Pointer,"%c",' ');
                }
                break;
            }else{
                fseek(disk_Pointer,3L,1);
            }
        }

        //清空磁盘文件和磁盘文件inode节点
        ifree(targetInodePointer->i_into);
        bfree(targetInodePointer->di_addr[0],targetInodePointer->file_size);

    
        //修改用户打开表
        currentUser_open_table.open_file_num--;
        for(i = 0; i <= 45; i++){
            if(strcmp(filename,currentUser_open_table.openFileNames[i]) == 0){
                strcpy(currentUser_open_table.openFileNames[i],"          ");
            }
        }

        //将删除后的文件的内存inode节点删除
        deleteInode(targetInodePointer);
        
        printf("文件删除成功!\n");
        return true;
    }
    else
    {
        printf("在外存中.....\n");
        int inodeNum = -1;
        fseek(disk_Pointer,3584 + 65,0);
        char currentFileName[10];
        char filenameProxy[10];
        strcpy(filenameProxy,filename);

        int fileRealLength = strlen(filename);
        //清空目录项的同时读取磁盘文件inode编号
        for(i = 0; i <= 39; i++){
            int j = 0;
            for(j = 0; j <= 9; j++){
                fscanf(disk_Pointer,"%c",&currentFileName[j]);
            }
            currentFileName[MAX_FILE_NAME_SIZE] = '\0';

            for(j = 0; j <= 9; j++){
                if(j >= fileRealLength){
                    filenameProxy[j] = ' ';
                }
            }
            filenameProxy[MAX_FILE_NAME_SIZE] = '\0';

        
            printf("currentFileName 的值是: %s\n",currentFileName);
            printf("长度为: %d\n",strlen(currentFileName));
            printf("filenameProxy的值是: %s\n",filenameProxy);
            printf("长度为: %d\n",strlen(filenameProxy));


            if(strcmp(filenameProxy,currentFileName) == 0){
                printf("相同!\n");
                fseek(disk_Pointer,1L,1);
                fscanf(disk_Pointer,"%d",&inodeNum);
                printf("inodeNum的值为: %d\n",inodeNum);
                fseek(disk_Pointer,-12L,1);
                //清空目录项
                for(j = 0; j <= 12; j++){
                    fprintf(disk_Pointer,"%c",' ');
                }
                break;
            }else{
                fseek(disk_Pointer,3L,1);
            }
        }

        if(inodeNum == -1){
            printf("无此文件!\n");
            return false;
        }else{
            int blockNum = -1;
            int fileSize = -1;
            //将指针定位到该磁盘inode处
            fseek(disk_Pointer,1536 + inodeNum * 50,0);
            
            //读取磁盘inode对应的文件起始数据盘块号
            fseek(disk_Pointer,1536 + inodeNum * 50 + 37,0);
            fscanf(disk_Pointer,"%d",&blockNum);
            printf("文件盘块起始地址为: %d\n",blockNum);
            //读取文件大小
            fseek(disk_Pointer,1536 + inodeNum * 50 + 35,0);
            fscanf(disk_Pointer,"%d",&fileSize);
            printf("文件大小为: %d\n",fileSize);
            //清空磁盘文件inode节点
            ifree(blockNum/512 - 9);
            //清空磁盘数据文件
            bfree(blockNum,fileSize);

            //修改超级块
            super_Block.fistack[inodeNum] = 0;
            super_Block.fbstack[blockNum/512] = 1;
            super_Block.fbstack[blockNum/512+1] = 1;
            super_Block.inum++;
            super_Block.bnum++;
            super_Block.s_fmod = 'y';
            super_Block.inode_bitmap[inodeNum] = 0;
            super_Block.block_bitmap[blockNum/512] = 0;
            super_Block.block_bitmap[blockNum/512+1] = 0;

            //修改当前用户子目录inode节点
            currentUserdirInode.di_number--;
            currentUserdirInode.i_flag = 'y';

            printf("文件删除成功!\n");
            return true;
        }
    }
}        



//文件关闭函数
bool closeFile(char *fileName)
{
    bool flag = false;
    int i = 0;
    int index = 0;
    Inode *targetInodePointer = NULL;
    if(strlen(fileName) > MAX_FILE_NAME_SIZE){
        flag = false;
        return flag;
    }

    for(i = 0; i <= 45; i++){
        if(strlen(currentUser_open_table.openFileNames[i]) > 0 && (strcmp(currentUser_open_table.openFileNames[i],"          ") != 0)){
            index++;
        }
        if(strcpy(currentUser_open_table.openFileNames[i],fileName) == 0){
            //修改用户打开表
            currentUser_open_table.open_file_num--;
            strcpy(currentUser_open_table.openFileNames[i],"          ");
            //遍历内存inode节点链表,找到对应该文件名的inode节点
            targetInodePointer = findInodeFromInodeList(index);
            if(targetInodePointer->i_flag == 'y'){
                //写回inode节点
                iset(targetInodePointer->i_into,targetInodePointer);
                deleteInode(targetInodePointer);
                flag = true;
                break;
            }else if(targetInodePointer->i_flag == 'n'){
                //删除内存inode节点
                if(targetInodePointer != NULL){
                    deleteInode(targetInodePointer);  
                    flag = true;
                    break;
                }else{
                    flag = false;
                    break;
                }
            }
        }
    }
    return flag;
}


//检查此用户是否是本文件系统的合法用户
bool islegalUser(struct Uid *uid)
{
    int i = 0;
    char user[10];
    //定义在校验用户名时的磁盘指针偏移量
    short int offset = 0;
    bool islegal = false;
    fseek(disk_Pointer,3584L,0);
    int index = 0;
    int realLength = strlen(uid->user_name);
    //将用户名填充至10个字节长度
    while(index <= (USERNAME_MAX_SIZE - 1)){
        if((index + 1) > realLength){
            uid->user_name[index] = ' ';
        }
        index++;
    }
    uid->user_name[USERNAME_MAX_SIZE] = '\0';
    printf("处理完后的用户名%s长度为%d",uid->user_name,strlen(uid->user_name));

    for(i = 0; i <= (USERNAME_MAX_SIZE - 1); i++){
        fscanf(disk_Pointer,"%c",&user[i]);
    }
    user[USERNAME_MAX_SIZE] = '\0';
    
    //当比较完所有的用户名时结束比较,共5个用户名
    while(offset <= 44){
        if(strcmp(user,uid->user_name) == 0){
            islegal = true;
            break;
        }else{
            offset = offset + 11;
            fseek(disk_Pointer,3L,1);
            for(i = 0; i <= (USERNAME_MAX_SIZE - 1); i++){
                fscanf(disk_Pointer,"%c",&user[i]);
            }
            user[USERNAME_MAX_SIZE] = '\0';
        }
    }
    return islegal;
}


//加载用户子目录inode节点
void loadSubDirInode(struct Uid *uid){
    int i = 0;
    char user[10];
    char empty[11] = "          ";
    //定义在校验用户名时的磁盘指针偏移量
    short int offset = 0;
    short int tatolOffset = 4 * DINODE_SIZE;
    fseek(disk_Pointer,1074L,0);

    while(offset <= tatolOffset){
        for(i = 0; i <= (USERNAME_MAX_SIZE - 1); i++){
            fscanf(disk_Pointer,"%c",&user[i]);
        }
        user[10] = '\0';

        printf("user 的值为: %s\n",user);
        printf("长度为: %d\n",strlen(user));
        printf("uid->user_name的值为: %s\n",uid->user_name);
        printf("uid->user_name的长度为: %d\n",strlen(uid->user_name));
        if(strcmp(user,uid->user_name) == 0){
            currentUserdirInode.i_forw = NULL;
            currentUserdirInode.i_back = NULL;
            currentUserdirInode.i_flag = 'n';
            currentUserdirInode.i_count = 0;
            //读取目录所属用户的用户名
            strcpy(currentUserdirInode.user_name,user);

            //读取关联文件数
            fseek(disk_Pointer,1L,1);
            fscanf(disk_Pointer,"%d",&currentUserdirInode.di_number);
            fseek(disk_Pointer,1L,1);

            //读取目录权限
            for(i = 0; i <= 10; i++){
                fscanf(disk_Pointer,"%c",&currentUserdirInode.i_mode[i]);
                fseek(disk_Pointer,1L,1);
            }
            //读取文件大小
            fscanf(disk_Pointer,"%d",&currentUserdirInode.file_size);
            fseek(disk_Pointer,1L,1);

            //读取磁盘块地址
            for(i = 0 ; i <= (FILE_MAX_BLOCK_NUM - 1); i++){
                fscanf(disk_Pointer,"%d",&(currentUserdirInode.di_addr[i]));
            }
            break;
        }else{
            fseek(disk_Pointer,-10L,1);
            offset = offset + 50;
            fseek(disk_Pointer,50,1);
            //strcpy(user,empty);
        }
    }
}


//用户登录函数
bool login()
{
    //用户重新登录的次数
    int reloginTime = 0;
    bool succeed = false;
    while(true){
        gets(uid.user_name);
        strcpy(realName,uid.user_name);
        if(islegalUser(&uid)){
            printf("%s\n","是合法用户");
            succeed = true;
            //将该用户对应的子目录inode节点加载到内存当中  
            loadSubDirInode(&uid);
            printf("登录成功,欢迎%s用户使用本文件系统!\n",uid.user_name);
            //改变当前目录提示符
            if(current_dir == NULL){
                current_dir = (char *)malloc(sizeof(char));
            }
            current_dir = realName;
            //初始化用户打开表
            strcpy(currentUser_open_table.user_name,uid.user_name);
            break;
        }else{
            reloginTime++;
            if(reloginTime == RELOGINTIME){
                //登录次数为RELOGINTIME时退出
                exit(0);
            }
            printf("用户名输入有误, 您还有%d次重复登录机会, 请核对后再输入!\n", (RELOGINTIME - reloginTime));
            printf("%s> ",current_dir);
        }
    }
    return succeed;
}


//用户退出函数
bool logout()
{
    int i = 0;
    //首先判断当前用户对应的磁盘子目录inode节点是否被修改过,修改则重新写入磁盘
    if(currentUserdirInode.i_flag == 'y'){
        //获得currentUserdirInode的物理盘块号
        int di_addr = currentUserdirInode.di_addr[0];
        fseek(disk_Pointer,di_addr,0);
        for(i = 0; i <= (USERNAME_MAX_SIZE - 1); i++){
            fprintf(disk_Pointer,"%c",currentUserdirInode.user_name[i]);
        }
        fprintf(disk_Pointer," %d ",currentUserdirInode.di_number);
        for(i = 0; i <= 10; i++){
            fprintf(disk_Pointer,"%c ",currentUserdirInode.i_mode[i]);
        }
        fprintf(disk_Pointer,"%d ",currentUserdirInode.file_size);
        //写回物理盘块号地址
        fprintf(disk_Pointer,"%d ",currentUserdirInode.di_addr[0]);
        fprintf(disk_Pointer,"%d ",currentUserdirInode.di_addr[1]);
    }

    //清空用户打开表和uid
    struct User_open_table *user_open_tablePointer = &currentUser_open_table;
    struct Uid *uidPointer = &uid;
    //free(user_open_tablePointer);
    //free(uidPointer);
    return true;
}





//退出文件系统函数
void halt()
{
    int size = 0;
    struct Inode *currentInodePointer = NULL;
    //首先检查超级块是否被修改
    if(super_Block.s_fmod == 'y'){
        fseek(disk_Pointer,0L,0);
        writeSuperBlock(0);
    }

    currentInodePointer = inodeListHead;
    //遍历内存inode节点链表,将修改的inode节点写回磁盘对应位置
    while(currentInodePointer != NULL){
        size++;
        printf("节点数目为: %d\n",size);
        if(currentInodePointer->i_flag == 'y'){
            //写回磁盘
            printf("待写入的磁盘地址为: %d\n",currentInodePointer->i_into);

            fseek(disk_Pointer,(1536 + currentInodePointer->i_into * 50),0);
            for(int i = 0; i <= (USERNAME_MAX_SIZE - 1); i++){
                fprintf(disk_Pointer,"%c",currentInodePointer->user_name[i]);
            }
            printf("当前用户为: %s\n",currentInodePointer->user_name);

            fprintf(disk_Pointer," %d ",currentInodePointer->di_number);
            printf("关联文件数为: %d\n",currentInodePointer->di_number);

            for(int j = 0; j <= 10; j++){
                fprintf(disk_Pointer,"%c ",currentInodePointer->i_mode[j]);
                printf("权限%d为: %c\n",j,currentInodePointer->i_mode[j]);
            }
            fprintf(disk_Pointer,"%d ",currentInodePointer->file_size);
            printf("文件大小为: %d\n",currentInodePointer->file_size);


            fprintf(disk_Pointer,"%d ",currentInodePointer->di_addr[0]);
            printf("文件地址1为: %d\n",currentInodePointer->di_addr[0]);

            fprintf(disk_Pointer,"%d ",currentInodePointer->di_addr[1]);
            printf("文件地址2为: %d\n",currentInodePointer->di_addr[1]);
        }
        //指针前移
        currentInodePointer = inodeListHead->i_back;
        inodeListHead->i_back = NULL;
        //回收节点
        free(inodeListHead);
        inodeListHead = currentInodePointer;
    }
}


//文件系统格式化函数
bool format()
{
    unsigned short int i = 0;
    unsigned short int j = 0;
    // 将文件指针定位到文件开始位置
    fseek(disk_Pointer,0L,0);
    // 格式化超级块
    writeSuperBlock(1);

    //格式化目录
    fseek(disk_Pointer,1024L,0);
    //首先将根目录inode节点写入磁盘文件
    //所属用户,默认为ROOT
    strcpy(dinode[0].user_name,"ROOT");
    for(i = 0; i <= 9; i++){
        if(i > 3){
            fprintf(disk_Pointer,"%c",' ');
        }else{
            fprintf(disk_Pointer,"%c",dinode[0].user_name[i]);
        }
    }
    //关联文件数,初始为0
    fprintf(disk_Pointer," %d ",dinode[0].di_number);    
    //存取权限,根目录所有所有权限均公开
    dinode[0].i_mode[0] = '1';   
    dinode[0].i_mode[1] = '1';
    dinode[0].i_mode[2] = '1';
    dinode[0].i_mode[3] = '1';
    dinode[0].i_mode[4] = '1';
    dinode[0].i_mode[5] = '1';
    dinode[0].i_mode[6] = '1';
    dinode[0].i_mode[7] = '1';
    dinode[0].i_mode[8] = '1';
    dinode[0].i_mode[9] = '1';
    dinode[0].i_mode[10] = '1';
    //将权限写入磁盘文件
    for(i = 0; i <= 10; i++){
        fprintf(disk_Pointer,"%c ",dinode[0].i_mode[i]);
    }
    //文件大小
    fprintf(disk_Pointer,"%d ",dinode[0].file_size);
    //写入物理盘块号地址
    dinode[0].di_addr[0]=1024;
    dinode[0].di_addr[1]=1024;
    fprintf(disk_Pointer,"%d ",dinode[0].di_addr[0]);

    //格式化子目录inode节点
    char *users_name[] = {"GAO","XU","LIU","WANG","JIANG"};
    for(i = 1; i <= 5; i++){
        fseek(disk_Pointer,1024 + i * 50,0);
        strcpy(dinode[i].user_name,users_name[i - 1]);
        for(j = 0; j <= (USERNAME_MAX_SIZE - 1); j++){
            if((j + 1) <= strlen(dinode[i].user_name)){
                fprintf(disk_Pointer,"%c",dinode[i].user_name[j]);
            }else{
                fprintf(disk_Pointer,"%c",' ');
            }
        }        
        fprintf(disk_Pointer," %d ",dinode[i].di_number);
        dinode[i].i_mode[0] = '1';   
        dinode[i].i_mode[1] = '1';
        dinode[i].i_mode[2] = '1';
        dinode[i].i_mode[3] = '1';
        dinode[i].i_mode[4] = '1';
        dinode[i].i_mode[5] = '1';
        dinode[i].i_mode[6] = '1';
        dinode[i].i_mode[7] = '0';
        dinode[i].i_mode[8] = '0';
        dinode[i].i_mode[9] = '0';
        dinode[i].i_mode[10] = '0';
        for(j = 0; j <= 10; j++){
            fprintf(disk_Pointer,"%c ",dinode[i].i_mode[j]);
        }
        fprintf(disk_Pointer,"%d ",dinode[i].file_size);
        //写入物理盘块号地址
        dinode[i].di_addr[0]=1024 + 50 * i;
        dinode[i].di_addr[1]=1024 + 50 * i;
        fprintf(disk_Pointer,"%d ",dinode[i].di_addr[0]);
        printf("%s\n","format finished....");
    }

    

    printf("%s\n","----------------------------------------------------");
    /****    格式化目录项    ****/
    fseek(disk_Pointer,3584L,0);
    printf("%s\n","+++++++++++++++++++++++++++++++++++++++++++++++++++++");
    
    //首先将根目录对应的五个目录项,即根目录下的5个子目录写入磁盘中
    for(i = 0; i <= 4; i++){
        strcpy(dir_entry[i].file_name,users_name[i]);
        //写入目录名
        for(j = 0; j <= (MAX_FILE_NAME_SIZE - 1); j++){
            if((j + 1) > strlen(dir_entry[i].file_name)){
                fprintf(disk_Pointer,"%c",' ');
            }else{
                fprintf(disk_Pointer,"%c",dir_entry[i].file_name[j]);
            }
        }
        //写入目录磁盘inode节点编号,和数据文件inode编号不同,分别为1,2,3,4,5号
        fprintf(disk_Pointer," %d ",i+1);
    }
    //将缓冲区中的内容输出到文件中
    fflush(disk_Pointer);
    return true;
}





//读超级块
void readSuperBlock(){
        int i = 0;
        for(i = 0; i <= 39; i++){
            fscanf(disk_Pointer,"%d",&super_Block.fistack[i]);
            fseek(disk_Pointer,1L,1);
        }
        fscanf(disk_Pointer,"%d",&super_Block.fiptr);
        fseek(disk_Pointer,1L,1);

        for(i = 0; i <= 99; i++){
            fscanf(disk_Pointer,"%d",&super_Block.fbstack[i]);
            fseek(disk_Pointer,1L,1);
        }
        fscanf(disk_Pointer,"%d",&super_Block.fbptr);
        fseek(disk_Pointer,1L,1);
        fscanf(disk_Pointer,"%d",&super_Block.inum);
        fseek(disk_Pointer,1L,1);
        fscanf(disk_Pointer,"%d",&super_Block.bnum);
        fseek(disk_Pointer,1L,1);
        fscanf(disk_Pointer,"%d",&super_Block.inodeNum);
        fseek(disk_Pointer,1L,1);
        fscanf(disk_Pointer,"%d",&super_Block.blockNum);
        fseek(disk_Pointer,1L,1);
        fscanf(disk_Pointer,"%c",&super_Block.s_fmod);
        fseek(disk_Pointer,1L,1);
        for(i = 0; i <= 39; i++){
            fscanf(disk_Pointer,"%d",&super_Block.inode_bitmap[i]);
            fseek(disk_Pointer,1L,1);
        }
        for(i = 0; i <= 99; i++){
            fscanf(disk_Pointer,"%d",&super_Block.block_bitmap[i]);
            fseek(disk_Pointer,1L,1);
        }
}


//进入文件系统函数
void install()
{
    int i = 0;
    readSuperBlock();

    //为inode链表头指针和尾指针分配空间
    inodeListHead = NULL;
    inodeListTail = NULL;

    //为用户打开表中的字符指针分配空间
    for(i = 0; i <= 45; i++){
        currentUser_open_table.openFileNames[i] = (char *)malloc(1);   
        //currentUser_open_table.openFileNames[i] = NULL;
    }
}


void showMenu(){
    system("cls");
    printf("\n\n\n\n\n");
    printf("\t|-----------------------------------------------|\n");
    printf("\t|              Command List                     |\n");
    printf("\t|--------------------------------------------   |\n");
    printf("\t|\t        of           打开文件            |\n");
    printf("\t|\t        cf           创建文件            |\n");
    printf("\t|\t        halt         退出系统            |\n");
    printf("\t|\t        logout       注销                |\n");
    printf("\t|\t        login        登录                |\n");
    printf("\t|\t        rf           读文件              |\n");
    printf("\t|\t        wf           写文件              |\n");
    printf("\t|\t        df           删除文件            |\n");
    printf("\t|\t        closefile    关闭文件            |\n");
    printf("\t|\t        man          查看命令列表        |\n");
    printf("\t|-----------------------------------------------|\n");
}



int main()
{
    //文件系统命令字符串数组
    char *command_Array[] = {"of","cf","halt","logout","login","rf","wf","df","closefile","man"};
    //磁盘大小
    int disk_size;
    //当前用户登录成功的标志
    bool has_Logined = false;
    //系统当前的状态
    bool isRunning = true;
    //用户输入的命令字符串
    char command[10];

    disk_Pointer = fopen("E:\\C示例程序\\File_system\\disk.txt","r+");
    //获取磁盘文件的大小
    fseek(disk_Pointer,0,SEEK_SET);
    fseek(disk_Pointer,0,SEEK_END);
    disk_size = ftell(disk_Pointer);
    //判断系统是否需要格式化
    if(disk_size == 0)
    {
        format();
    }
    //将超级块加载到内存
    fseek(disk_Pointer,0L,0);
    install();
    showSuperBlock();
    


    //提示用户登录文件系统
    printf("请输入用户名登录文件系统\n");
    printf("%s> ",current_dir);
    has_Logined = login();
    //响应用户输入命令
    while(isRunning == true){
        printf("%s> ",current_dir);
        gets(command);
        if(strlen(command) == 0){
            //回车换行
        }else if(strcmp(command,command_Array[3]) == 0){
            //用户退出
            logout();
            strcpy(current_dir,"ROOT");
            has_Logined = false;
        }else if(strcmp(command,command_Array[0]) == 0){
            //打开文件
            char *file_Name = NULL;
            printf("请输入文件名: \n");
            gets(file_Name);
            if(openFile(file_Name) == true){
                printf("文件打开成功!\n");
            }else{
                printf("不存在该文件!\n");
            }

        }else if(strcmp(command,command_Array[1]) == 0){
            char *file_Name = NULL;
            char *file_Content = "empty";
            file_Name = (char *)malloc(1);
            file_Content = (char *)malloc(1);
            //创建文件
            printf("请输入文件名: \n");
            gets(file_Name);
            printf("请输入文件内容: \n");
            gets(file_Content);
            if(createFile(file_Name,file_Content) == true){
                printf("文件创建成功!\n");
            }
        }else if(strcmp(command,command_Array[2]) == 0){
            //关闭文件系统
            if(has_Logined == true){
                logout();
            }
            halt();
            isRunning = false;
        }else if(strcmp(command,command_Array[5]) == 0){
            //读文件
            char *file_Name = "no file";
            printf("请输入文件名: \n");
            gets(file_Name);
            readFile(file_Name);
        }else if(strcmp(command,command_Array[6]) == 0){
            //写文件
            char *file_Name = "no file";
            printf("请输入文件名: \n");
            gets(file_Name);
            writeFile(file_Name);
        }else if(strcmp(command,command_Array[7]) == 0){
            //删除文件
            char *file_Name = NULL;
            file_Name = (char *)malloc(1);
            printf("请输入文件名: \n");
            gets(file_Name);
            if(deleteFile(file_Name) == true){
                printf("文件删除成功!\n");
            }
        }else if(strcmp(command,command_Array[8]) == 0){
            //关闭文件
            char *file_Name = "no file";
            printf("请输入文件名: \n");
            gets(file_Name);
            if(closeFile(file_Name) == true){
                printf("文件成功关闭!\n");
            }else{
                printf("文件关闭失败!\n");
            }
        }else if(strcmp(command,command_Array[9]) == 0){
            //打印命令菜单
            showMenu();
        }else{
            showInfo("无效命令,请重新输入!\n");
        }
    }
    fclose(disk_Pointer);
    return 0;
}