DHU 多用户多级目录文件系统实验

来源:互联网 发布:centos vim 安装 编辑:程序博客网 时间:2024/05/07 12:35

实验报告链接:http://wenku.baidu.com/view/6a5c51276c175f0e7dd1370d.html

代码                :若显示脚本提示,连续点否即可正常浏览

/*******************************************Project: 实验四——文件系统v1.0              *Author : J_Dark                            *Date   : 2013/12/16 15:18                  *********************************************/#include  <conio.h>#include  <io.h>#include  <cstdlib>#include  <malloc.h>#include  <fstream>#include  <iostream>#include  <string>#include  <cstdio>#include  <queue>#include  <algorithm>#include  <vector>#include  <string>#include  <cstring>#include  <time.h>#define NULL 0#define MAX_DISK_LEN54120// 模拟硬盘最大存储量#define MAX_BLOCK_LEN120// 单个物理块最大容量#define MAX_BLOCK_NUM452// 硬盘划分物理块数+1#define MAX_USER_NUM6// 可创建用户最大数#define MAX_CHILD_NUM    10// 每一级目录下最大可创建文件数#define MAX_SHARE_NUM9// 每个用户最多可共享文件数#define MAX_FILE_NUM401// 文件系统最大可创建文件数+1#define MAX_FILENAME_LEN10// 文件名最大长度#define MFD_BLOCK_START1#define MFD_BLOCK_END1#define MAX_FILECONTENT_LEN16// 数据文件内容最大长度#define MFD_MAX_LEN20// 单个MFD文件最大长度#define MFD_START_POS0// MFD区硬盘开始位置#define MFD_END_POS100// MFD区硬盘结束位置#define INDEX_FILE_BLOCK_START2#define INDEX_FILE_BLOCK_END51#define INDEX_FILE_LEN20// 单个索引文件表项最大长度#define INDEX_FILE_START_POS120// 索引文件表区硬盘开始位置#define INDEX_FILE_END_POS6100// 索引文件表区硬盘结束位置#define INDEX_DATA_BLOCK_START52#define INDEX_DATA_BLOCK_END451#define INDEX_DATA_LEN60// 数据文件索引节点最大长度#define INDEX_DIR_LEN120// 目录文件索引节点最大长度#define INDEX_CHILD_LEN4// 子项索引编号长度#define INDEX_DATA_START_POS6120// 索引节点区硬盘开始位置#define INDEX_DATA_END_POS54000// 索引节点区硬盘结束位置#define get(type) (type *)malloc(sizeof(type)) // 分配空间using namespace std;///////////////////////////////////////////////////////////////////////////////// 索引节点(硬盘索引/内存索引)struct Index{// 当前索引所指向文件int     IndexNo;// 索引编号3Bchar    FileName[MAX_FILENAME_LEN];// 文件名(规定数据文件名10B/目录文件名9B)10B/9Bint     StartPos;// 硬盘存储开始位置5BintBlockId;// 硬盘存储物理块编号4BintType;// 文件类型0/1  数据文件/目录文件 1BintLen;// 数据文件长度2Bchar    Content[MAX_FILECONTENT_LEN];   // 数据文件内容16BintMode;// 保护码0/1   只读/可读写1BboolState;// 文件状态0/1  关闭状态/打开状态 1BboolShare;// 文件共享状态,0/1  不共享/共享1Bchar    TimeCreate[8], TimeRecUse[8];// 文件创建时间/文件最近使用时间16B// 若当前索引指向目录 int ParentDirNo;// 父目录索引节点编号3Bint ChlidDirList[MAX_CHILD_NUM];// 子目录/文件索引表40B// 若当前索引指向用户根目录int ShareList[MAX_SHARE_NUM];// 用户共享文件索引表   36B// PS: 规定ChlidDirList与ShareList中索引号以*为分隔符};// 文件索引20Bstruct indexlist{char FileName[MAX_FILENAME_LEN]; //10B 索引文件名int  IndexNo; //3B  索引编号int  StartPos; //5B  索引编号对应索引节点存储开始位置int  Type; // 1B  索引文件类型};// 主文件目录 MFD20Bstruct User{char   UserName[MAX_FILENAME_LEN];// 用户名10Bint    IndexNo;// UFD索引编号3Bint   StartPos;// UFD硬盘存储开始位置4Bint    BlockId;// UFD硬盘存储物理块编号2B};// 空闲块表(硬盘空间管理/首次适应算法)struct fdt// FreeDiskTable{int  StartPos;// 空闲块开始位置int  EmptyId;// 空闲块所在物理块编号int  OccuLen;// 已占用长度int  MaxLen;// 可占用最大长度bool IsFull;// 是否占用};// 文件打开表 已打开文件struct oft// OpenFileTable{char FileName[20];// 文件名int  Type;// 文件类型 0/1   数据文件/目录文件int  Mode;// 保护码0/1   只读/可读写bool State;// 状态0/1  建立/打开int StartPos;// 存储区开始地址};// 通过RequestDisk操作申请到的空闲区域struct reqblock{int ReqStPos;int EmptyId;};struct listpath{int IndexNo;char FileName[20];};// 空闲表优先级排序函数bool cmp(fdt a, fdt b){return a.StartPos < b.StartPos;}///////////////////////////////////////////////////////////////////////////////class FileManager{public:FileManager(void);~FileManager(void);// 磁盘操作void  IntToString(int Source, char *Dest);void  GetTime(char *Time);    void  DiskRead(int StartPos, int ReadLen, char* Reader);// 读取硬盘数据操作void  DiskWrite(int StartPos, char* Writer);// 写入硬盘数据操作//void  DiskDel(int DelLen, int DataType);// 删除硬盘数据操作bool  RequestDisk(int ReqLen, int DataType, struct reqblock &ReqBlock);// 申请硬盘空间void  CopyIndexData(struct Index &CopyIndex, int IndexNo, int Type);// 拷贝硬盘索引节点—>内存索引节点// 空闲表操作void InitFDT();// 初始化void DelFDT(int StPos, int Type);// 清除表项// 文件打开表操作void InitOFT();// 初始化void DelOFT(int StPos);// 清除表项bool OperOFT(int OP, char* FileName, int StPos);// 1/2   打开/关闭文件void OperOFT(int OP);// 1/2 读/写文件void InitIndexList();// 初始化内存索引文件表void Top();// 文件系统置顶显示信息void UMI();// 用户管理界面 User Management Interfacevoid FMI();// 文件管理界面 File Management Interface    void CreateUser();// 创建用户void ListUser();// 显示系统所有用户void Login();// 用户登录void CreateFile(int Type);// 新建文件/目录void ShowFile();// 显示当前目录下所有目录及文件void ShowPath();// 显示当前访问路径void DeleteFile(int Type);// 删除文件/目录void OpenFile(int Type);// 打开文件/目录void CloseFile();// 关闭文件void SetShare();// 设置文件共享void AbolishShare();// 取消文件共享void Rename(int Type);// 重命名文件/文件夹void Back();// 返回上一层目录private:charDisk[MAX_DISK_LEN];// 模拟硬盘indexlistIndexList[MAX_FILE_NUM];// 内存索引文件表fdtFDT[MAX_BLOCK_NUM];// 硬盘空闲块分配表oftOFT[MAX_FILE_NUM];// 文件打开表IndexCurrDir;// 当前目录索引UserCurrUser;// 当前用户intUserCount;// 用户数目intEmpBlockNum;// 空闲块数intIndexNoNum;// 索引节点编号数int         IndexFileNum;// 索引文件表表项数int         OpenFileNum;listpathListPath[MAX_FILE_NUM];// 存储路径索引编号;int         ListPathNum;// 访问路径数目};FileManager::FileManager(void){EmpBlockNum = MAX_BLOCK_NUM;IndexNoNum = 0;IndexFileNum = 0;OpenFileNum  = 0;ListPathNum  = 0;UserCount    = 0;memset(Disk, '\0', sizeof(Disk));// 初始化硬盘InitFDT();// 初始化空闲表InitOFT();// 初始化文件打开表InitIndexList();// 初始化内存索引文件表}FileManager::~FileManager(void){}// 整数转字符串函数void  FileManager::IntToString(int Source, char *Dest){memset(Dest, '\0', sizeof(Dest));itoa(Source, Dest, 10);}// 获取当前系统时间函数void  FileManager::GetTime(char *Time){memset(Time, '\0', sizeof(Time));struct tm *local;time_t t;t = time(NULL);local = localtime(&t);// 记录当前yearIntToString((local->tm_year)+1900, Time);char Dest1[10], Dest2[10];IntToString(0, Dest2);// 将0转换为字符串IntToString((local->tm_mon)+1, Dest1); // 记录当前monthif(Dest1[1] == '\0'){strcat(Dest2, Dest1);strcat(Time, Dest2);}else strcat(Time, Dest1);IntToString(0, Dest2);// 将0转换为字符串memset(Dest1, '\0',sizeof(Dest1));IntToString(local->tm_mday, Dest1); // 记录当前dayif(Dest1[1] == '\0'){strcat(Dest2, Dest1);strcat(Time, Dest2);}else strcat(Time, Dest1);}// 申请硬盘空间bool FileManager::RequestDisk(int ReqLen, int DataType, struct reqblock &ReqBlock){// 申请用户区硬盘空间if(DataType == 1) {if(!FDT[1].IsFull && (FDT[1].MaxLen-FDT[1].OccuLen)>=ReqLen)// 用户区所在物理块未满且满足申请需求{ReqBlock.EmptyId = FDT[1].EmptyId;// 记录空闲块信息ReqBlock.ReqStPos = FDT[1].StartPos;FDT[1].StartPos = FDT[1].StartPos + ReqLen;FDT[1].OccuLen += ReqLen;// 更新空闲块if(FDT[1].OccuLen == FDT[1].MaxLen)FDT[1].IsFull = true;printf("\n\t用户区申请硬盘空间成功!");sort(FDT+1, FDT+EmpBlockNum, cmp);// 按照起始地址升序更新空闲表return true;}else{printf("\n\t用户区硬盘已满或存储不足,申请空间失败!");return false;}}// 申请索引文件表区硬盘空间if(DataType == 2){for(int i=2; i<=51; i++)// 遍历空闲表索引文件表区所在物理块{if(!FDT[i].IsFull)// 索引文件表区所在物理块未满{if((FDT[i].MaxLen-FDT[i].OccuLen)>=ReqLen)// 索引文件表区所在物理块满足申请需求{ReqBlock.EmptyId = FDT[i].EmptyId;// 记录空闲块信息ReqBlock.ReqStPos = FDT[i].StartPos;int FindNum = 1;for(int iFind=FDT[i].StartPos; iFind<=INDEX_FILE_END_POS; iFind+=INDEX_FILE_LEN){if(Disk[iFind]!='\0')FindNum++;elsebreak;}FDT[i].StartPos += (FindNum*ReqLen);FDT[i].OccuLen += ReqLen;// 更新空闲块if(FDT[i].OccuLen == FDT[i].MaxLen)FDT[i].IsFull = true;printf("\n\t索引文件表区申请硬盘空间成功!");sort(FDT+1, FDT+EmpBlockNum, cmp);// 按照起始地址升序更新空闲表return true;}}}printf("\n\t索引文件表区硬盘已满或存储不足,申请空间失败!");return false;}// 申请索引节点区硬盘空间if(DataType == 3){for(int i=52; i<=451; i++)// 遍历空闲表索引节点区所在物理块{if(!FDT[i].IsFull)// 索引索引节点区所在物理块未满{if((FDT[i].MaxLen-FDT[i].OccuLen)>=ReqLen)// 索引节点区区所在物理块满足申请需求{ReqBlock.EmptyId = FDT[i].EmptyId;// 记录空闲块信息ReqBlock.ReqStPos = FDT[i].StartPos;if(ReqLen == INDEX_DATA_LEN){if(Disk[i*MAX_BLOCK_LEN-ReqLen] != '\0')FDT[i].StartPos = FDT[i].StartPos + 2*ReqLen;elseFDT[i].StartPos = FDT[i].StartPos + ReqLen;}elseFDT[i].StartPos = FDT[i].StartPos + ReqLen;FDT[i].OccuLen += ReqLen;// 更新空闲块if(FDT[i].OccuLen == FDT[i].MaxLen)FDT[i].IsFull = true;printf("\n\t索引节点区申请硬盘空间成功!");sort(FDT+1, FDT+EmpBlockNum, cmp);// 按照起始地址升序更新空闲表return true;}}}printf("\n\t索引节点区硬盘已满或存储不足,申请空间失败!");return false;}return false;}// 读取硬盘数据操作void FileManager::DiskRead(int StartPos, int ReadLen, char* Reader){memset(Reader, '\0', sizeof(Reader));int ReadNum;for(ReadNum = 0; ReadNum<ReadLen && Disk[StartPos+ReadNum]!='\0'; ReadNum++){Reader[ReadNum] = Disk[StartPos+ReadNum];}Reader[ReadNum] = '\0';}// 写入硬盘数据操作void FileManager:: DiskWrite(int StartPos, char* Writer){int WriteNum;for(WriteNum=0; WriteNum<strlen(Writer); WriteNum++){Disk[StartPos+WriteNum] = Writer[WriteNum];}Disk[StartPos+WriteNum] = '\0';}// 清除空闲表项void FileManager::DelFDT(int StPos=0, int Type=0){int Id = (StPos/120)+1;if(Id>=2 && Id<=51)// 修改文件表区物理块{int  FindNum = 0;for(int iFind=StPos; iFind<=INDEX_FILE_END_POS; iFind+=INDEX_FILE_LEN){if(Disk[iFind] != '\0')FindNum++;elsebreak;}FindNum++;FDT[Id].OccuLen -= (FindNum*INDEX_FILE_LEN);FDT[Id].IsFull = false;FDT[Id].StartPos -= (FindNum*INDEX_FILE_LEN);}if(Id>=52 && Id<=451)// 修改索引节点区物理块{if(Type == 0){FDT[Id].OccuLen -= INDEX_DATA_LEN;if((StPos%INDEX_DIR_LEN) == 0){if(FDT[Id].IsFull)FDT[Id].StartPos -= INDEX_DIR_LEN;elseFDT[Id].StartPos -= INDEX_DATA_LEN;}else{if(FDT[Id].IsFull)FDT[Id].StartPos -= INDEX_DATA_LEN;elseFDT[Id].StartPos -= INDEX_DIR_LEN;}FDT[Id].IsFull = false;}else{FDT[Id].OccuLen -= INDEX_DIR_LEN;FDT[Id].IsFull = false;FDT[Id].StartPos -= INDEX_DIR_LEN;}}sort(FDT+1, FDT+EmpBlockNum, cmp);}// 初始化空闲表void FileManager::InitFDT(){for(int i=1; i<MAX_BLOCK_NUM; i++){FDT[i].MaxLen = MAX_BLOCK_LEN;FDT[i].EmptyId = i;FDT[i].OccuLen = 0;FDT[i].StartPos = 120*(i-1);FDT[i].IsFull = false;}}// 初始化索引文件表void FileManager::InitIndexList(){for(int i=1; i<MAX_FILE_NUM; i++){memset(IndexList[i].FileName, '\0', sizeof(IndexList[i].FileName));}}// 打开/关闭/文件bool FileManager::OperOFT(int OP, char* FileName, int StPos=0){if(OP == 1) // 打开文件{bool IsOpen = false;int Pos;for(int i=1; i<MAX_FILE_NUM; i++){if(strcmp(OFT[i].FileName, FileName)==0 && OFT[i].StartPos == StPos){IsOpen = true;Pos = i;break;}}if(!IsOpen)return false;else{if(!OFT[Pos].State)printf("\n\t文件%s正建立,无法打开!(需要写入)\n", FileName);elseprintf("\n\t文件%s已打开!\n", FileName);getch();FMI();return true;}}if(OP == 2)// 关闭文件{bool IsClose = false;int Pos=-1;for(int i=1; i<MAX_FILE_NUM; i++){if(strcmp(OFT[i].FileName, FileName)==0 && OFT[i].StartPos == StPos){//IsClose = true;Pos = i;break;}}if(Pos == -1 || !OFT[Pos].State)printf("\n\t文件%s已关闭,无法重复关闭!\n", FileName);else{memset(OFT[Pos].FileName, '\0', sizeof(OFT[Pos].FileName)); // 清除表项printf("\n\t文件%s关闭成功!\n", FileName);}getch();FMI();return true;}}// 读/写文件void FileManager::OperOFT(int OP){system("cls");if(OP == 1)// 读文件{char ReadFile[20];char cIndexNo[20], sIndexNo[20], Read[20];bool IsChild = false;int StPos, key;do{Top();printf("\t*                    读取文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t1. 读取共享文件\n");printf("\t2. 读取子目录文件\n");printf("\n\t请选择:");scanf("%d", &key);}while(key!=1 && key !=2);if(key == 1){if(CurrDir.ParentDirNo != 0){printf("\n\t当前目录不是用户目录,无法读取共享文件!");getch();OperOFT(1);}else{system("cls");Top();printf("\t*                    读取文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件名: ");    scanf("%s",  ReadFile);for(int i=CurrDir.StartPos+81; i<CurrDir.StartPos+117; i+=INDEX_CHILD_LEN)// 遍历硬盘索引CurrDir的ShareList{DiskRead(i, 4, Read);if(Read[0] != '\0')  // 获取共享文件索引编号{// 遍历硬盘索引文件表strcpy(sIndexNo, Read);for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(sIndexNo, Read)==0)// 命中共享文件{DiskRead(k, 10, Read);if(strcmp(ReadFile, Read)==0) // CurrDir下存在待关闭文件{IsChild = true;DiskRead(k+13, 5, Read);StPos = atoi(Read);break;}}}}if(IsChild)   break;}}}if(key == 2){system("cls");Top();printf("\t*                    读取文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件名: ");scanf("%s",  ReadFile);for(int i=0; i<MAX_CHILD_NUM; i++)// 遍历内存索引CurrDir的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 获取子目录索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);// 获取对应文件名if(strcmp(ReadFile, Read)==0){IsChild = true;DiskRead(k+13, 5, Read);StPos = atoi(Read);break;}}}if(IsChild)break;}}if(!IsChild){if(key == 2)printf("\n\t当前目录下无%s文件,无法读取!", ReadFile);elseprintf("\n\t当前用户不共享%s文件,无法读取!", ReadFile);}else{bool IsOpen = false;int Pos;for(int i=1; i<MAX_FILE_NUM; i++){if(strcmp(OFT[i].FileName, ReadFile)==0 && OFT[i].StartPos == StPos){IsOpen = true;Pos = i;break;}}if(!IsOpen)printf("\n\t文件%s未打开,无法读取!", ReadFile);else{char Read[20];DiskRead(OFT[Pos].StartPos+42, 16, Read);printf("\n\t读取文件%s内容如下 \n", ReadFile);printf("\n\t: %s\n", Read);}   }getch();FMI();}if(OP == 2) // 写文件{char WriteFile[20];char ReadFile[20];char cIndexNo[20], sIndexNo[20], Read[20];bool IsChild = false;int StPos, key;do{Top();printf("\t*                    写入文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t1. 写入共享文件\n");printf("\t2. 写入子目录文件\n");printf("\n\t请选择:");scanf("%d", &key);}while(key!=1 && key !=2);if(key == 1){if(CurrDir.ParentDirNo != 0){printf("当前目录不是用户目录,无法写入共享文件!");getch();OperOFT(2);}else{system("cls");Top();printf("\t*                    写入文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件名: ");    scanf("%s",  WriteFile);for(int i=CurrDir.StartPos+81; i<CurrDir.StartPos+117; i+=INDEX_CHILD_LEN)// 遍历硬盘索引CurrDir的ShareList{DiskRead(i, 4, Read);if(Read[0] != '\0')  // 获取共享文件索引编号{// 遍历硬盘索引文件表strcpy(sIndexNo, Read);for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(sIndexNo, Read)==0)// 命中共享文件{DiskRead(k, 10, Read);if(strcmp(WriteFile, Read)==0) // CurrDir下存在待关闭文件{IsChild = true;DiskRead(k+13, 5, Read);StPos = atoi(Read);break;}}}}if(IsChild)   break;}}}if(key == 2){system("cls");Top();printf("\t*                    写入文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件名: ");scanf("%s",  WriteFile);for(int i=0; i<MAX_CHILD_NUM; i++)// 遍历内存索引CurrDir的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 获取子目录索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);// 获取对应文件名if(strcmp(WriteFile, Read)==0){IsChild = true;DiskRead(k+13, 5, Read);StPos = atoi(Read);break;}}}if(IsChild)break;}}// 公操作区if(!IsChild){if(key == 2)printf("\n\t当前目录下无%s文件,无法写入!", WriteFile);elseprintf("\n\t当前用户不共享%s文件,无法写入!", WriteFile);}else{bool IsOpen = false;int Pos;for(int i=1; i<MAX_FILE_NUM; i++){if(strcmp(OFT[i].FileName, WriteFile)==0 && OFT[i].StartPos == StPos){IsOpen = true;Pos = i;break;}}if(!IsOpen)// 待写入文件不在OFT中printf("\n\t文件%s尚未建立或打开,无法写入!", WriteFile);else{char Write[20];if(!OFT[Pos].State)// 文件为建立状态{do{printf("\n\t输入写入内容(长度<=16)\n");printf("\n\t: ");scanf("%s", Write);}while(strlen(Write)>MAX_FILECONTENT_LEN);DiskWrite(OFT[Pos].StartPos+42, Write);// 写入硬盘OFT[Pos].State = true;// 建立状态->打开状态printf("\n\t写入文件%s成功! \n", WriteFile);}else// 文件为打开状态{DiskRead(OFT[Pos].StartPos+39, 2, Read);int Len = atoi(Read);if(OFT[Pos].Mode == 1)// 文件可读写{do{printf("\n\t输入写入内容(长度<=%d)\n", Len);printf("\n\t: ");scanf("%s", Write);}while(strlen(Write)>Len);DiskWrite(OFT[Pos].StartPos+42, Write); // 写入硬盘printf("\n\t写入文件%s成功! \n", WriteFile);}else// 文件只读,不可写入{printf("\n\t文件%s只读,无法写入!\n", WriteFile);}}}}getch();FMI();}}// 清除文件打开表项void FileManager::DelOFT(int StPos){for(int iDel=1; iDel<MAX_FILE_NUM; iDel++){if(OFT[iDel].StartPos == StPos){memset(OFT[iDel].FileName, '\0', sizeof(OFT[iDel].FileName));OFT[iDel].Mode = -1;OFT[iDel].StartPos = -1;OFT[iDel].State = false;OFT[iDel].Type - 1;}}}// 初始化文件打开表void FileManager::InitOFT(){for(int i=1; i<MAX_FILE_NUM; i++){memset(OFT[i].FileName, '\0', sizeof(OFT[i].FileName));}}// 拷贝硬盘索引节点—>内存索引节点void FileManager::CopyIndexData(struct Index &CopyIndex, int IndexNo, int Type){char Source[4];int StPos;IntToString(IndexNo, Source);for(int i=INDEX_FILE_START_POS; i<=INDEX_FILE_END_POS; i+=INDEX_FILE_LEN){char Read[50];DiskRead(i, 10, Read);strcpy(CopyIndex.FileName, Read);DiskRead(i+10, 3, Read);// 获取文件表索引编号if(strcmp(Source, Read) == 0)   // 命中{DiskRead(i+13, 5, Read);StPos = atoi(Read);CopyIndex.IndexNo = IndexNo;CopyIndex.StartPos = StPos;CopyIndex.BlockId = (StPos/120)+1;if(Type == 1)// 目录文件{CopyIndex.Type = 1;// 读取父目录索引编号DiskRead(StPos+38, 3, Read);CopyIndex.ParentDirNo = atoi(Read);// 读取子目录/索引文件表//DiskRead(StPos+41, 40, Read);int k, m=0, ChildNum=0;char temp[10];memset(CopyIndex.ChlidDirList, '\0', sizeof(CopyIndex.ChlidDirList));for(k=StPos+41; k<StPos+81; k+=INDEX_CHILD_LEN){for(int n=0; n<4; n++){if(Disk[k+n] != '\0')temp[m++] = Disk[k+n];else{temp[m] = '\0';CopyIndex.ChlidDirList[ChildNum++] = atoi(temp);m = 0;break;}}}// 拷贝目录为用户目录 读取用户共享文件索引表if(CopyIndex.ParentDirNo == 0){m=0;int ShareNum=0;memset(temp, '\0', sizeof(temp));memset(CopyIndex.ShareList, '\0', sizeof(CopyIndex.ShareList));for(k=StPos+81; k<StPos+117; k+=INDEX_CHILD_LEN){for(int n=0; n<4; n++){if(Disk[k+n] != '\0')temp[m++] = Disk[k+n];else{temp[m] = '\0';CopyIndex.ShareList[ShareNum++] = atoi(temp);m = 0;break;}}}}}else// 数据文件{CopyIndex.Type = 0;CopyIndex.State = true;// 读取数据长度DiskRead(StPos+39, 2, Read);CopyIndex.Len = atoi(Read);// 读取文件内容DiskRead(StPos+42, 16, Read);strcpy(CopyIndex.Content, Read);// 读取保护码DiskRead(StPos+41, 1, Read);CopyIndex.Mode = atoi(Read);// 读取文件共享状态DiskRead(StPos+58, 1, Read);CopyIndex.Mode = atoi(Read);}break;}}}void FileManager::Top(){printf("\t*****************************************************\n");printf("\t*             欢迎使用元杰文件系统v1.0              *\n");printf("\t*                                                   *\n");printf("\t*   SNo:111310228  Author: J_Dark  Class:计算机1102 *\n");printf("\t*---------------------------------------------------*\n");}void FileManager::UMI(){system("cls");int key;Top();    //printf("\t*---------------------------------------------------*\n");printf("\t*                    用户功能选择                   *\n");printf("\t*           1.用户登录         2.创建用户           *\n");printf("\t*           3.查看用户         4.退出系统           *\n");printf("\t*---------------------------------------------------*\n");    printf("\t请选择: ");scanf("%d", &key); switch(key){   case 1:   Login();   FMI();   break;   case 2:   CreateUser();   break;        case 3:   ListUser();    getchar();   getchar();   UMI();   break;   case 4:   system("cls");    printf("感谢使用!下次再会!\n");   getch();   exit(0);   break;   default :   printf("\n\n\t\t\t输入错误,请重新输入\n");   getch();   UMI();   break;    }}void FileManager::FMI(){int key;system("cls");Top();printf("\t*                  数据文件功能选择                 *\n");printf("\t*          10.新建文件         11.删除文件          *\n");printf("\t*          12.打开文件         13.关闭文件          *\n");printf("\t*          14.读文件           15.写文件            *\n");printf("\t*          16.设置文件共享     17.取消文件共享      *\n");printf("\t*          18.重命名文件                            *\n");printf("\t*---------------------------------------------------*\n");printf("\t*                   目录文件功能选择                *\n");printf("\t*          20.新建文件夹       21.删除文件夹        *\n");printf("\t*          22.打开文件夹       23.重命名文件夹      *\n");printf("\t*---------------------------------------------------*\n");printf("\t*                     系统功能选择                  *\n");printf("\t*          30.显示路径         31.显示子目录及文件  *\n");printf("\t*          32.返回上一层       33.退出登录          *\n");printf("\t*****************************************************\n");printf("\t请选择操作: ");scanf("%d",&key);printf("\n");system("cls");switch(key) //switch语句{  case 10:CreateFile(0);// 新建文件break;     case 11:DeleteFile(0);// 删除文件break;              case 20:CreateFile(1);// 新建文件夹break;     case 21:DeleteFile(1);// 删除文件夹break;       case 12:OpenFile(0);// 打开文件break; case 22:OpenFile(1);// 打开文件夹break;case 14:OperOFT(1);// 读出文件break;              case 15:OperOFT(2);// 写入文件break;      case 18:// 重命名文件Rename(0);break;case 23:// 重命名文件夹Rename(1);break;case 16:// 共享文件SetShare();break;case 17:// 撤消共享文件AbolishShare();break;case 13:CloseFile();// 关闭文件break;     case 31:ShowFile();// 显示文件(夹)getch();FMI();break;case 32:Back();// 返回上一层break;      case 33:for(int k=0; k<MAX_FILE_NUM; k++) // 初始化访问路径{ListPath[k].IndexNo = 0;memset(ListPath[k].FileName, '\0', sizeof(ListPath[k].FileName));}ListPathNum = 0;UMI();// 退出登录break;        case 30:ShowPath();// 显示路径break;default :{printf("\n 选择错误,请重新选择\n");    getch();    FMI();    break;}}}// 创建用户void FileManager::CreateUser(){char NewUser[MAX_FILENAME_LEN];system("cls");Top();printf("\t*                    创建用户                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入用户名: ");scanf("%s", NewUser);for(int i=MFD_START_POS; i<=MFD_END_POS; i+= MFD_MAX_LEN){char tUserName[MAX_FILENAME_LEN];DiskRead(i, 10, tUserName);if(strcmp(NewUser, tUserName)==0)// 如果该系统已经存在该用户,则不能创建{printf("\n\t该用户已存在,无法创建\n");getch();system("cls");UMI();}}// 申请MFD硬盘空间reqblock MFD_ReqBlock, IF_ReqBlock, ID_ReqBlock;bool IsRequest = false;if( RequestDisk(MFD_MAX_LEN, 1, MFD_ReqBlock)){// 申请索引节点区硬盘空间if( RequestDisk(INDEX_DIR_LEN, 3, ID_ReqBlock)){// 申请索引文件表区硬盘空间if( RequestDisk(INDEX_FILE_LEN, 2, IF_ReqBlock)){IsRequest = true;IndexNoNum++;char Dest[20];// 写入索引节点IntToString(IndexNoNum, Dest);DiskWrite(ID_ReqBlock.ReqStPos, Dest);// 索引号 3BDiskWrite(ID_ReqBlock.ReqStPos+3, NewUser);// 目录名 9BIntToString(ID_ReqBlock.ReqStPos, Dest);// 存储开始位置 5BDiskWrite(ID_ReqBlock.ReqStPos+12, Dest);IntToString(ID_ReqBlock.EmptyId, Dest);// 存储物理块号 4BDiskWrite(ID_ReqBlock.ReqStPos+17, Dest);IntToString(1, Dest);// 文件类型:目录文件 1BDiskWrite(ID_ReqBlock.ReqStPos+21, Dest);// 文件创建时间/最近使用时间 16Bchar Tc[20], Tu[20];GetTime(Tc);strcpy(Tu, Tc);DiskWrite(ID_ReqBlock.ReqStPos+22, Tc);// 文件创建时间 8BDiskWrite(ID_ReqBlock.ReqStPos+30, Tc);// 文件最近使用时间 8BIntToString(0, Dest);// 用户父目录索引编号为0DiskWrite(ID_ReqBlock.ReqStPos+38, Dest);// 写入MFDDiskWrite(MFD_ReqBlock.ReqStPos, NewUser);// 用户名 10BIntToString(IndexNoNum, Dest);// 索引号 3BDiskWrite(MFD_ReqBlock.ReqStPos+10, Dest);IntToString(MFD_ReqBlock.ReqStPos, Dest);// 存储开始位置 4BDiskWrite(MFD_ReqBlock.ReqStPos+13, Dest);IntToString(MFD_ReqBlock.EmptyId, Dest);// 存储物理块号 2BDiskWrite(MFD_ReqBlock.ReqStPos+17, Dest);// 写入硬盘文件表DiskWrite(IF_ReqBlock.ReqStPos, NewUser);// 文件名 10BIntToString(IndexNoNum, Dest);DiskWrite(IF_ReqBlock.ReqStPos+10, Dest);// 索引号 3BIntToString(ID_ReqBlock.ReqStPos, Dest);// 存储开始位置 5BDiskWrite(IF_ReqBlock.ReqStPos+13, Dest);IntToString(1, Dest);// 文件类型 1BDiskWrite(IF_ReqBlock.ReqStPos+18, Dest);}}}if(IsRequest){UserCount++;char key;printf("\n\n\t用户创建成功!\n");getch();UMI();}else{ printf("\n\n\t当前用户数已达上限,不可创建用户!\n"); getch(); UMI();}}// 显示用户void FileManager::ListUser(){system("cls");Top();printf("\t*                    用户清单                       *\n");    printf("\t*---------------------------------------------------*\n\n");int Count=0;for(int i=MFD_START_POS; i<=MFD_END_POS; i+= MFD_MAX_LEN){char tUserName[MAX_FILENAME_LEN];DiskRead(i, 10, tUserName);if(tUserName[0] != '\0')    printf("\n\t\t\t第%d个用户: %s", ++Count, tUserName);}}// 用户登录void FileManager::Login(){char LoginUser[10];system("cls");Top();printf("\t*                    用户登录                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入用户名: ");scanf("%s", LoginUser);      //输入用户名bool IsLogin = false;for(int i=MFD_START_POS; i<=MFD_END_POS; i+= MFD_MAX_LEN){char tUserName[MAX_FILENAME_LEN];DiskRead(i, 10, tUserName);if(strcmp(LoginUser, tUserName)==0){ IsLogin = true;char Dest[25];strcpy(CurrUser.UserName, tUserName); // 登记当前用户DiskRead(i+10, 3, Dest);CurrUser.IndexNo = atoi(Dest);DiskRead(i+13, 4, Dest);CurrUser.StartPos = atoi(Dest);DiskRead(i+17, 2, Dest);CurrUser.BlockId = atoi(Dest);strcpy(CurrDir.FileName, LoginUser); // 登记当前目录-用户目录CurrDir.IndexNo = CurrUser.IndexNo;CopyIndexData(CurrDir, CurrUser.IndexNo, 1); // 从硬盘拷贝用户索引文件节点// 清空OFTInitOFT();// 登记OFTfor(int i=1; i<MAX_FILE_NUM; i++){if(OFT[i].FileName[0] == '\0'){strcpy(OFT[i].FileName, LoginUser);OFT[i].StartPos = CurrUser.StartPos;OFT[i].State = true;OFT[i].Type = 1;OpenFileNum++;break;}} for(int k=0; k<MAX_FILE_NUM; k++) // 初始化访问路径{ListPath[k].IndexNo = 0;memset(ListPath[k].FileName, '\0', sizeof(ListPath[k].FileName));} ListPath[++ListPathNum].IndexNo = CurrDir.IndexNo; // 记录访问路径strcpy(ListPath[ListPathNum].FileName, CurrDir.FileName);    break;}}if(!IsLogin)// 如果该系统已经存在该用户,转FMI界面{printf("\n\t用户登录失败!\n");getch();UMI();}}// 显示当前访问路径void FileManager::ShowPath(){Top();printf("\n\t当前路径:");for(int i=1; ListPath[i].IndexNo!=0; i++)printf(" %s/", ListPath[i].FileName);printf("\n");getch();FMI();}void FileManager::Back(){    // 拷贝CurrDir父目录索引->CurrDirif(CurrDir.ParentDirNo !=0){CopyIndexData(CurrDir, CurrDir.ParentDirNo, 1);ListPath[ListPathNum].IndexNo = 0;memset(ListPath[ListPathNum].FileName, '\0', sizeof(ListPath[ListPathNum].FileName));ListPathNum--;}FMI(); // 返回文件管理操作菜单}// 新建文件(夹)void FileManager::CreateFile(int Type){char NewFile[MAX_FILENAME_LEN];system("cls");Top();// 新建文件if(Type == 0) {printf("\t*                    新建文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件名: ");scanf("%s", NewFile);// 检查是否重名char cIndexNo[20], Read[20];int m=0;for(int i=0; i<MAX_CHILD_NUM; i++)// 遍历内存索引CurrDir的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 获取子目录索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);// 获取对应文件名if(strcmp(NewFile, Read)==0){printf("\n\t当前目录下文件/文件夹重名,请更换文件名\n");getch();system("cls");CreateFile(0);}}}}//设置文件属性int Mode, Len;printf("\n\t设置文件属性(只读0  可读写1): ");    scanf("%d", &Mode);while(Mode!=0 && Mode!=1){printf("\n\t设置错误,请重新设置!");scanf("%d", &Mode);}printf("\n\t设置文件长度: ");scanf("%d", &Len);reqblock IF_ReqBlock, ID_ReqBlock;bool IsRequest = false;bool IsAddChild = false;// 登记CurrDir,写入索引节点区// 申请索引节点区硬盘空间if( RequestDisk(INDEX_DATA_LEN, 3, ID_ReqBlock)){// 申请索引文件表区硬盘空间if( RequestDisk(INDEX_FILE_LEN, 2, IF_ReqBlock)){IsRequest = true;IndexNoNum++;char Dest[20];// 更新CurrDir的硬盘子项索引表与内存子项索引表for(int i=CurrDir.StartPos+41; i<CurrDir.StartPos+81; i+=INDEX_CHILD_LEN){if(Disk[i] == '\0'){IntToString(IndexNoNum, Dest);int k = i;for(int j=0; j<strlen(Dest); j++)Disk[k++] = Dest[j];IsAddChild = true;for(int iAdd=0; iAdd<MAX_CHILD_NUM; iAdd++){if(CurrDir.ChlidDirList[iAdd] == 0){ CurrDir.ChlidDirList[iAdd] = IndexNoNum; break;}}break;}}if(IsAddChild){// 写入索引节点IntToString(IndexNoNum, Dest);DiskWrite(ID_ReqBlock.ReqStPos, Dest);// 索引号 3BDiskWrite(ID_ReqBlock.ReqStPos+3, NewFile);// 文件名 10BIntToString(ID_ReqBlock.ReqStPos, Dest);// 存储开始位置 5BDiskWrite(ID_ReqBlock.ReqStPos+13, Dest);IntToString(ID_ReqBlock.EmptyId, Dest);// 存储物理块号 4BDiskWrite(ID_ReqBlock.ReqStPos+18, Dest);IntToString(0, Dest);// 文件类型:数据文件 1BDiskWrite(ID_ReqBlock.ReqStPos+22, Dest);// 文件创建时间/最近使用时间 16Bchar Tc[20], Tu[20];GetTime(Tc);strcpy(Tu, Tc);DiskWrite(ID_ReqBlock.ReqStPos+23, Tc);// 文件创建时间 8BDiskWrite(ID_ReqBlock.ReqStPos+31, Tu);// 文件最近使用时间 8BIntToString(Len, Dest);// 文件长度 2BDiskWrite(ID_ReqBlock.ReqStPos+39, Dest);IntToString(Mode, Dest);// 文件保护码 1BDiskWrite(ID_ReqBlock.ReqStPos+41, Dest);IntToString(0, Dest);// 默认文件不共享 1BDiskWrite(ID_ReqBlock.ReqStPos+58, Dest);// 写入硬盘文件表DiskWrite(IF_ReqBlock.ReqStPos, NewFile);// 文件名 10BIntToString(IndexNoNum, Dest);DiskWrite(IF_ReqBlock.ReqStPos+10, Dest);// 索引号 3BIntToString(ID_ReqBlock.ReqStPos, Dest);// 存储开始位置 5BDiskWrite(IF_ReqBlock.ReqStPos+13, Dest);IntToString(0, Dest);// 文件类型 1BDiskWrite(IF_ReqBlock.ReqStPos+18, Dest);// 登记OFTbool IsAdd = false;for(int i=1; i<MAX_FILE_NUM; i++){if(OFT[i].FileName[0] == '\0'){strcpy(OFT[i].FileName, NewFile);OFT[i].StartPos = ID_ReqBlock.ReqStPos;OFT[i].State = false;// 建立状态OFT[i].Mode = Mode;OFT[i].Type = 0;// 登记数据文件OpenFileNum++;IsAdd = true;break;}}if(!IsAdd)printf("\n\t当前已打开文件数已达上限,无法添加文件打开表!\n"); }}}if(IsRequest && IsAddChild)printf("\n\n\t文件创建成功!\n");elseprintf("\n\n\t当前文件数已达上限,无法新建文件!\n"); }// 新建文件夹else    {printf("\t*                    新建文件夹                     *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件夹名: ");scanf("%s", NewFile);// 检查是否重名char cIndexNo[20], Read[20];int m=0;for(int i=0; i<MAX_CHILD_NUM; i++)// 遍历内存索引CurrDir的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 获取子目录索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);// 获取对应文件名if(strcmp(NewFile, Read)==0){printf("\n\t当前目录下文件/文件夹重名,请更换文件夹名\n");getch();system("cls");CreateFile(1);}}}}reqblock IF_ReqBlock, ID_ReqBlock;bool IsRequest = false;bool IsAddChild = false;// 登记CurrDir,写入索引节点区// 申请索引节点区硬盘空间if( RequestDisk(INDEX_DIR_LEN, 3, ID_ReqBlock)){// 申请索引文件表区硬盘空间if( RequestDisk(INDEX_FILE_LEN, 2, IF_ReqBlock)){IsRequest = true;IndexNoNum++;char Dest[20];// 更新CurrDir的硬盘子项索引表与内存子项索引表for(int i=CurrDir.StartPos+41; i<CurrDir.StartPos+81; i+=INDEX_CHILD_LEN){if(Disk[i] == '\0'){IntToString(IndexNoNum, Dest);int k = i;for(int j=0; j<strlen(Dest); j++)Disk[k++] = Dest[j];IsAddChild = true;for(int iAdd=0; iAdd<40; iAdd++){if(CurrDir.ChlidDirList[iAdd] == 0){ CurrDir.ChlidDirList[iAdd] = IndexNoNum; break;}}break;}}// 写入索引节点if(IsAddChild){IntToString(IndexNoNum, Dest);DiskWrite(ID_ReqBlock.ReqStPos, Dest);// 索引号 3BDiskWrite(ID_ReqBlock.ReqStPos+3, NewFile);// 目录文件名 9BIntToString(ID_ReqBlock.ReqStPos, Dest);// 存储开始位置 5BDiskWrite(ID_ReqBlock.ReqStPos+12, Dest);IntToString(ID_ReqBlock.EmptyId, Dest);// 存储物理块号 4BDiskWrite(ID_ReqBlock.ReqStPos+17, Dest);IntToString(0, Dest);// 文件类型:数据文件 1BDiskWrite(ID_ReqBlock.ReqStPos+21, Dest);// 文件创建时间/最近使用时间 16Bchar Tc[20], Tu[20];GetTime(Tc);strcpy(Tu, Tc);DiskWrite(ID_ReqBlock.ReqStPos+22, Tc);// 文件创建时间 8BDiskWrite(ID_ReqBlock.ReqStPos+30, Tu);// 文件最近使用时间 8BIntToString(CurrDir.IndexNo, Dest);// 父目录索引节点 3BDiskWrite(ID_ReqBlock.ReqStPos+38, Dest);// 写入硬盘文件表DiskWrite(IF_ReqBlock.ReqStPos, NewFile);// 文件名 10BIntToString(IndexNoNum, Dest);DiskWrite(IF_ReqBlock.ReqStPos+10, Dest);// 索引号 3BIntToString(ID_ReqBlock.ReqStPos, Dest);// 存储开始位置 5BDiskWrite(IF_ReqBlock.ReqStPos+13, Dest);IntToString(1, Dest);// 文件类型 1BDiskWrite(IF_ReqBlock.ReqStPos+18, Dest);}}}if(IsRequest && IsAddChild)printf("\n\n\t文件夹创建成功!\n");else{ printf("\n\n\t当前文件数已达上限,无法新建文件夹!\n");}}getch();FMI();}// 删除文件(夹)void FileManager::DeleteFile(int Type){char DelFile[20];Top();if(Type == 0){printf("\t*                    删除文件                       *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件名: ");}else{printf("\t*                    删除文件夹                     *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入文件夹名: ");}scanf("%s", DelFile);// 查找CurrDir是否有待删除文件char cIndexNo[20], Read[20];int m=0;bool IsDel = false;for(int i=0; i<MAX_CHILD_NUM; i++) // 遍历CurrDir内存索引节点的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);if(strcmp(DelFile, Read)==0) // CurrDir下存在待删除文件{IsDel = true;int StPos;// 清除CurrDir硬盘节点中记录for(int iDel=CurrDir.StartPos+41; iDel<CurrDir.StartPos+81; iDel+=INDEX_CHILD_LEN){DiskRead(iDel, 3, Read);if(strcmp(cIndexNo, Read)==0){for(int iiDel=0; iiDel<INDEX_CHILD_LEN; iiDel++)Disk[iDel+iiDel] = '\0'; break;}}  // 清除CurrDir内存节点中记录CurrDir.ChlidDirList[i] = 0; DiskRead(k+13, 5, Read);StPos = atoi(Read);// 若在OFT中,清除表项DelOFT(StPos);int Dist;if(Type == 0)Dist = 60;elseDist = 120;// 归还索引节点区存储空间for(int iDel=StPos; iDel<StPos+Dist; iDel++)Disk[iDel] = '\0';// 归还文件表区存储空间for(int iDel=k; iDel<k+INDEX_FILE_LEN; iDel++)Disk[iDel] = '\0';// 更新索引节点区空闲表DelFDT(StPos, Type);// 更新索文件表区空闲表DelFDT(k);break;}}}}if(!IsDel){printf("\n\t当前目录下不存在该文件,无法删除\n");printf("\n\t请核对文件名!\n");}else{if(Type == 0) printf("\n\t文件%s已删除!\n", DelFile);else  printf("\n\t文件夹%s已删除!\n", DelFile);}getch();FMI();}// 显示CurrDir下的文件/目录void FileManager::ShowFile(){Top();printf("\t*             当前目录下的文件和文件夹              *\n");printf("\t*---------------------------------------------------*\n\n");if(CurrDir.ParentDirNo == 0)  // 当前目录为用户目录 显示共享文件{printf("\n共享文件: \n");printf("\n文件名 文件类型 文件属性 共享状态 存储块 存储起始位 创建时间 最近使用\n\n");char sIndexNo[20], Read[20];int StPos;for(int i=CurrDir.StartPos+81; i<CurrDir.StartPos+117; i+=INDEX_CHILD_LEN)// 遍历硬盘索引CurrDir的ShareList{DiskRead(i, 4, Read);if(Read[0] != '\0')  // 获取子目录索引编号{// 遍历硬盘索引文件表strcpy(sIndexNo, Read);for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(sIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k+13, 5, Read);StPos = atoi(Read);char s1[10],s2[10],s3[10],s4[10],s5[10],s6[10],s7[10], s8[10];DiskRead(StPos+3, 10, Read);strcpy(s1, Read);// 输出文件名strcpy(s2, "数据文件");// 输出文件类型DiskRead(StPos+41, 1, Read);// 输出文件属性if(atoi(Read) == 0) strcpy(s3, "只  读");else strcpy(s3, "可读写");strcpy(s4, "共享");// 输出共享状态DiskRead(StPos+18, 4 , Read);// 输出存储块strcpy(s5, Read);DiskRead(StPos+13, 5 , Read);// 输出存储起始位strcpy(s6, Read);DiskRead(StPos+23, 8 , Read);// 输出创建时间strcpy(s7, Read);DiskRead(StPos+31, 8, Read);// 输出最近使用时间strcpy(s8, Read);//printf("文件名 文件类型 文件属性 共享状态 存储块 存储起始位 创建时间 最近使用\n");printf("%s    %s %s     %s     %s     %s     %s %s\n", s1, s2, s3, s4, s5, s6, s7, s8);break;}}}}}printf("\n*--------------------------------------------------------------------*\n");bool IsChild = false;for(int i=0; i<MAX_CHILD_NUM; i++){if(CurrDir.ChlidDirList[i]!=0){IsChild = true;break;}}if(!IsChild){printf("\n当前目录下无子文件和子目录!\n");return;}else{printf("\n子文件及目录: \n");printf("\n文件名 文件类型 文件属性 共享状态 存储块 存储起始位 创建时间 最近使用\n\n");char rIndexNo[20];for(int i=0; i<MAX_CHILD_NUM; i++) // 遍历CurrDir内存索引节点的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], rIndexNo);char Read[20];for(int n=INDEX_FILE_START_POS; n<=INDEX_FILE_END_POS; n+=INDEX_FILE_LEN)  // 遍历文件表获取节点区开始位置{DiskRead(n+10, 3, Read);if(strcmp(rIndexNo, Read)==0){DiskRead(n+13, 5, Read);int StPos = atoi(Read);// 获取节点区开始位置int Type;DiskRead(n+18, 1, Read);// 获取文件类型Type = atoi(Read);char s1[10],s2[10],s3[10],s4[10],s5[10],s6[10],s7[10], s8[10];if(Type == 0)// 命中数据文件{DiskRead(StPos+3, 10, Read);strcpy(s1, Read);// 输出文件名strcpy(s2, "数据文件");// 输出文件类型DiskRead(StPos+41, 1, Read);// 输出文件属性if(atoi(Read) == 0) strcpy(s3, "只  读");else strcpy(s3, "可读写");DiskRead(StPos+58, 1 , Read);// 输出共享状态if(atoi(Read) == 0)  strcpy(s4, "私有");else strcpy(s4, "共享");DiskRead(StPos+18, 4 , Read);// 输出存储块strcpy(s5, Read);DiskRead(StPos+13, 5 , Read);// 输出存储起始位strcpy(s6, Read);DiskRead(StPos+23, 8 , Read);// 输出创建时间strcpy(s7, Read);DiskRead(StPos+31, 8, Read);// 输出最近使用时间strcpy(s8, Read);//printf("文件名 文件类型 文件属性 共享状态 存储块 存储起始位 创建时间 最近使用\n");printf("%s    %s %s     %s     %s     %s     %s %s\n", s1, s2, s3, s4, s5, s6, s7, s8);}else// 命中目录文件{DiskRead(StPos+3, MAX_CHILD_NUM, Read); strcpy(s1, Read);// 输出文件名strcpy(s2, "目录文件");// 输出文件类型DiskRead(StPos+17, 4 , Read);// 输出存储块strcpy(s3, Read);DiskRead(StPos+12, 5 , Read);// 输出存储起始位strcpy(s4, Read);DiskRead(StPos+22, 8 , Read);// 输出创建时间strcpy(s5, Read);DiskRead(StPos+30, 8, Read);// 输出最近使用时间strcpy(s6, Read);//printf("文件名 文件类型 文件属性 共享状态 存储块 存储起始位 创建时间 最近使用\n");printf("%s    %s                     %s     %s     %s %s\n", s1, s2, s3, s4, s5, s6);}break;}}}}// 显示共享文件(包括其他用户共享文件)}// 打开文件(夹)void FileManager::OpenFile(int Type){char OpenFile[20];Top();if(Type == 0){printf("\t*                    打开文件                       *\n");printf("\t*---------------------------------------------------*\n\n");}else{printf("\t*                    打开文件夹                     *\n");printf("\t*---------------------------------------------------*\n\n");}// 查找CurrDir是否有待打开文件char cIndexNo[20], Read[20];bool IsOpen = false;bool IsChild = false;if(CurrDir.ParentDirNo == 0 && Type == 0)   // 用户目录,可选择打开共享文件{char key;char sIndexNo[20], sFile[20], Read[20];int StPos, Mode;printf("\n\t是否打开共享文件(Y/N)? ");scanf("%s", &key);if(key == 'Y' || key == 'y'){printf("\n\t请输入文件名: ");scanf("%s", sFile);for(int i=CurrDir.StartPos+81; i<CurrDir.StartPos+117; i+=INDEX_CHILD_LEN)// 遍历硬盘索引CurrDir的ShareList{DiskRead(i, 4, Read);if(Read[0] != '\0')  // 获取共享文件索引编号{// 遍历硬盘索引文件表strcpy(sIndexNo, Read);for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(sIndexNo, Read)==0)// 命中共享文件{DiskRead(k+18, 1, Read);if(Type == atoi(Read)){IsChild = true;DiskRead(k, 10, Read);DiskRead(k+13, 5, Read);StPos = atoi(Read);DiskRead(StPos+41, 1, Read);Mode = atoi(Read);if(OperOFT(1, sFile, StPos));// 共享文件是否已在OFT中else{bool IsAdd = false;for(int i=1; i<MAX_FILE_NUM; i++){if(OFT[i].FileName[0] == '\0'){strcpy(OFT[i].FileName, sFile);OFT[i].StartPos = StPos;OFT[i].State = true;// 打开状态OFT[i].Mode = Mode;OFT[i].Type = 0;// 登记数据文件OpenFileNum++;IsAdd = true;break;}}if(!IsAdd){printf("\n\t当前已打开文件已达上限,无法打开!\n");getch();FMI();}}printf("\n\t共享文件%s已打开!\n", sFile);}}}}}}if(!IsChild && (key=='Y' || key=='y')){printf("\n\t当前用户不共享该文件,无法打开!\n");}printf("\n\t*---------------------------------------------------*\n\n");printf("\n\t是否打开子目录文件(Y/N)? ");scanf("%s", &key);if(key == 'Y' || key == 'y')goto T;elsegoto T1;}T:if(Type == 0)printf("\t请输入文件名:");elseprintf("\t请输入文件夹名: ");scanf("%s", OpenFile);IsChild = false;for(int i=0; i<MAX_CHILD_NUM; i++) // 遍历CurrDir内存索引节点的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);if(strcmp(OpenFile, Read)==0) // CurrDir下存在待打开文件{DiskRead(k+18, 1, Read);if(Type == atoi(Read)){IsChild = true;if(Type == 0)// 打开文件为数据文件{int StPos, Mode;// 登记OFTDiskRead(k+13, 5, Read);StPos = atoi(Read);DiskRead(StPos+41, 1, Read);Mode = atoi(Read);if(OperOFT(1, OpenFile, StPos));// 文件是否已在OFT中else{bool IsAdd = false;for(int i=1; i<MAX_FILE_NUM; i++){if(OFT[i].FileName[0] == '\0'){strcpy(OFT[i].FileName, OpenFile);OFT[i].StartPos = StPos;OFT[i].State = true;// 打开状态OFT[i].Mode = Mode;OFT[i].Type = 0;// 登记数据文件OpenFileNum++;IsAdd = true;break;}}if(!IsAdd){printf("\n\t当前已打开文件已达上限,无法打开!\n");getch();FMI();}}}else// 打开文件为目录,拷贝打开目录->CurrDir{strcpy(CurrDir.FileName, OpenFile);CurrDir.IndexNo = atoi(cIndexNo);CopyIndexData(CurrDir, atoi(cIndexNo), 1);ListPath[++ListPathNum].IndexNo = atoi(cIndexNo);strcpy(ListPath[ListPathNum].FileName, OpenFile);//break;}if(Type == 0)printf("\n\t文件%s已打开!\n", OpenFile);elseprintf("\n\t文件夹%s已打开!\n", OpenFile);}getch();FMI();}}}}if(!IsChild){printf("\n\t当前目录下不存在该文件,无法打开!\n");printf("\t请核对文件名!\n");}else{getch(); FMI();}T1:getch();FMI();}// 关闭文件void FileManager::CloseFile(){char CloseFile[20];Top();printf("\t*                    关闭文件                       *\n");printf("\t*---------------------------------------------------*\n\n");// 查找CurrDir下是否有待打开文件char cIndexNo[20], Read[20];bool IsClose = false;bool IsChild = false;if(CurrDir.ParentDirNo == 0)   // 用户目录可对共享文件进行关闭{char key;char sIndexNo[20], sFile[20], Read[20];int StPos, Mode;printf("\n\t是否关闭共享文件(Y/N)? ");scanf("%s", &key);if(key == 'Y' || key == 'y'){printf("\n\t请输入文件名: ");scanf("%s", CloseFile);for(int i=CurrDir.StartPos+81; i<CurrDir.StartPos+117; i+=INDEX_CHILD_LEN)// 遍历硬盘索引CurrDir的ShareList{DiskRead(i, 4, Read);if(Read[0] != '\0')  // 获取共享文件索引编号{// 遍历硬盘索引文件表strcpy(sIndexNo, Read);for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(sIndexNo, Read)==0)// 命中共享文件{DiskRead(k, 10, Read);if(strcmp(CloseFile, Read)==0) // CurrDir下存在待关闭文件{IsChild = true;DiskRead(k+13, 5, Read);StPos = atoi(Read);if(OperOFT(2, CloseFile, StPos));// OFT中关闭操作//printf("\n\t共享文件%s已关闭!\n", CloseFile);//break;}}}}}}if(!IsChild && (key=='Y' || key=='y')){printf("\n\t当前用户不共享该文件,无法关闭!\n");}printf("\n\t*---------------------------------------------------*\n\n");printf("\n\t是否关闭子目录文件(Y/N)? ");scanf("%s", &key);if(key == 'Y' || key == 'y')goto T;elsegoto T1;}T:IsChild = false;printf("\n\t请输入文件名: ");scanf("%s", CloseFile);for(int i=0; i<MAX_CHILD_NUM; i++) // 遍历CurrDir内存索引节点的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);if(strcmp(CloseFile, Read)==0) // CurrDir下存在待关闭文件{IsChild = true;DiskRead(k+13, 5, Read);int StPos = atoi(Read);if(OperOFT(2, CloseFile, StPos));// OFT中关闭操作//printf("\n\t共享文件%s已关闭!\n", CloseFile);break;}}}}if(!IsChild){printf("\n\t当前目录下不存在该文件,无法关闭!\n");printf("\n\t请核对文件名!\n");}else{getch(); FMI();}T1:getch();FMI();}// 重命名文件(夹)void FileManager::Rename(int Type){system("cls");char NewName[20], OldName[20];char cIndexNo[20], Read[20], sIndexNo[20];bool IsChild = false;int IdStPos, IfStPos;Top();if(Type == 0){printf("\t*                    重命名文件                     *\n");printf("\t*---------------------------------------------------*\n\n");    //printf("\t请输入预操作文件名: ");}else{printf("\t*                    重命名文件夹                   *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入预操作文件夹名: ");scanf("%s", OldName);}// 检查CurrDir下是否存在待打开文件if(CurrDir.ParentDirNo == 0 && Type == 0){system("cls");int key;do{system("cls");Top();printf("\t*                    重命名文件                     *\n");printf("\t*---------------------------------------------------*\n\n");printf("\n\t1. 重命名共享文件\n");printf("\n\t2. 重命名子目录文件\n");printf("\n\n\t请选择:");scanf("%d", &key);}while(key!=1 && key!=2);if(key == 1){system("cls");Top();printf("\t*                    重命名文件                     *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入预操作文件夹名: ");scanf("%s", OldName);for(int i=CurrDir.StartPos+81; i<CurrDir.StartPos+117; i+=INDEX_CHILD_LEN)// 遍历硬盘索引CurrDir的ShareList{DiskRead(i, 4, Read);if(Read[0] != '\0')  // 获取共享文件索引编号{// 遍历硬盘索引文件表strcpy(sIndexNo, Read);for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(sIndexNo, Read)==0)// 命中共享文件{DiskRead(k, 10, Read);if(strcmp(OldName, Read)==0) // CurrDir下存在待关闭文件{IsChild = true;IfStPos = k;DiskRead(k+13, 5, Read);IdStPos = atoi(Read);break;}}}}if(IsChild)break;}}else goto T;}T:if(Type == 0){system("cls");Top();printf("\t*                    重命名文件                     *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入预操作文件夹名: ");scanf("%s", OldName);}for(int i=0; i<MAX_CHILD_NUM; i++)// 遍历内存索引CurrDir的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 获取子目录索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);// 获取对应文件名if(strcmp(OldName, Read)==0){IsChild = true;IfStPos = k;DiskRead(k+13, 5, Read);IdStPos = atoi(Read);break;}}}if(IsChild)break;}// 公操作if(!IsChild){printf("\n\t当前目录下无%s文件,无法重命名!", OldName);}else{system("cls");Top();if(Type == 0)printf("\t*                    重命名文件                     *\n");elseprintf("\t*                    重命名文件夹                   *\n");printf("\t*---------------------------------------------------*\n\n");if(Type == 0)  printf("\n\t请输入新文件名: ");else           printf("\n\t请输入新文件夹名: ");scanf("%s", NewName);// 更新OFTfor(int i=1; i<MAX_FILE_NUM; i++){if(strcmp(OFT[i].FileName, OldName)==0 && OFT[i].StartPos == IdStPos){strcpy(OFT[i].FileName, NewName);break;}}// 更新文件表for(int i=IfStPos; i<IfStPos+10; i++)  // 清空旧文件名Disk[i] = '\0';DiskWrite(IfStPos, NewName);//写入文件表// 更新索引节点区int Dist;if(Type == 0)Dist = 10;elseDist = 9;for(int i=IdStPos+3; i<IdStPos+3+Dist; i++)  // 清空旧文件名Disk[i] = '\0';DiskWrite(IdStPos+3, NewName);//写入文件表if(Type == 0)  printf("\n\t文件%s重命名成功,新文件名为%s!", OldName, NewName);else           printf("\n\t文件夹%s重命名成功,新文件夹名为%s!", OldName, NewName);}getch();FMI();}// 设置文件共享标识void FileManager::SetShare(){char SSFile[20], SSIndexNo[5];Top();printf("\t*                    设置文件共享                   *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入预设置文件名: "); scanf("%s", SSFile);// 针对CurrDir下的文件进行操作// 检查CurrDir下是否存在待共享文件char cIndexNo[20], Read[20];bool IsChild = false;int IdStPos;for(int i=0; i<MAX_CHILD_NUM; i++)// 遍历内存索引CurrDir的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 获取子目录索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);if(strcmp(SSFile, Read) == 0){IsChild = true;strcpy(SSIndexNo, cIndexNo);DiskRead(k+13, 5, Read);IdStPos = atoi(Read);break;}}}if(IsChild)break;}if(!IsChild){printf("\n\t当前目录下无%s文件,无法设置共享!", SSFile);}else{bool IsShare = false;char UserName[20], UserIndexNo[5];int UserStPos, Count=0;// 设置该文件共享->将其IndexNo添加进每个用户的ShareListfor(int i=MFD_START_POS; i<=MFD_END_POS; i+=MFD_MAX_LEN){DiskRead(i, 10, Read);strcpy(UserName, Read);if(UserName[0] != '\0'){DiskRead(i+10, 3, Read);strcpy(UserIndexNo, Read);// 获取用户索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(UserIndexNo, Read)==0)// 命中用户索引文件表位置{DiskRead(k, 10, Read);// 获取用户名if(strcmp(UserName, Read)==0){//IsChild = true;DiskRead(k+13, 5, Read);UserStPos = atoi(Read); // 获取用户索引节点区起始位// 更新用户的硬盘共享索引表bool IsAddShare = false, IsShare = false;// 检查用户是否已共享过该文件for(int i=UserStPos+81; i<UserStPos+117; i+=INDEX_CHILD_LEN){DiskRead(i, 4, Read);if(strcmp(Read, SSIndexNo)== 0){IsShare = true;break;}}if(!IsShare){for(int i=UserStPos+81; i<UserStPos+117; i+=INDEX_CHILD_LEN){if(Disk[i] == '\0'){int k = i;for(int j=0; j<strlen(SSIndexNo); j++)Disk[k++] = SSIndexNo[j];IsAddShare = true;break;}}}elseprintf("\n\t用户%s已共享该文件,无需重复设置!", UserName);if(!IsAddShare && !IsShare){printf("\n\t用户%s当前共享文件数已达上限,设置该用户共享文件失败!", UserName);}else{Count++;printf("\n\t用户%s共享文件成功!", UserName);}break;}}}}}// 修改共享标志位if(Count != 0){IntToString(1, Read);DiskWrite(IdStPos+58, Read);printf("\n\t文件%s设置共享成功!", SSFile);}else{printf("\n\t文件%s设置共享失败!", SSFile);printf("\n\t当前所有用户共享文件数已达上限!");}}getch();FMI();}// 取消文件共享标识void FileManager::AbolishShare(){char ASFile[20], ASIndexNo[5];Top();printf("\t*                    取消文件共享                   *\n");printf("\t*---------------------------------------------------*\n\n");printf("\t请输入预设置文件名: "); scanf("%s", ASFile);// 针对CurrDir下的文件进行操作char cIndexNo[20], Read[20];bool IsChild = false;int IdStPos;for(int i=0; i<MAX_CHILD_NUM; i++)// 遍历内存索引CurrDir的ChlidDirList{if(CurrDir.ChlidDirList[i] == 0)continue;IntToString(CurrDir.ChlidDirList[i], cIndexNo);// 获取子目录索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(cIndexNo, Read)==0)// 命中子目录文件表位置{DiskRead(k, 10, Read);if(strcmp(ASFile, Read) == 0){IsChild = true;strcpy(ASIndexNo, cIndexNo);DiskRead(k+13, 5, Read);IdStPos = atoi(Read);break;}}}if(IsChild)break;}if(!IsChild)printf("\n\t当前用户不是%s文件创建者,故无法取消共享!", ASFile);else{bool IsShare = false;char UserName[20], UserIndexNo[5];int UserStPos, Count=0;// 取消文件共享->清除每个用户ShareList中的IndexNofor(int i=MFD_START_POS; i<=MFD_END_POS; i+=MFD_MAX_LEN){DiskRead(i, 10, Read);strcpy(UserName, Read);if(UserName[0] != '\0'){DiskRead(i+10, 3, Read);strcpy(UserIndexNo, Read);// 获取用户索引编号// 遍历硬盘索引文件表for(int k=INDEX_FILE_START_POS; k<=INDEX_FILE_END_POS; k+=INDEX_FILE_LEN){DiskRead(k+10, 3, Read);if(strcmp(UserIndexNo, Read)==0)// 命中用户索引文件表位置{DiskRead(k, 10, Read);// 获取用户名if(strcmp(UserName, Read)==0){DiskRead(k+13, 5, Read);UserStPos = atoi(Read);// 获取用户索引节点区起始位// 更新用户的硬盘共享索引表bool IsAblosh = false;// 检查用户是否已共享过该文件for(int i=UserStPos+81; i<UserStPos+117; i+=INDEX_CHILD_LEN){DiskRead(i, 4, Read);if(strcmp(Read, ASIndexNo)== 0) // 该用户共享该文件{for(int iDel=0; iDel<4; iDel++)  // 清除ShareList标识{Disk[i+iDel] = '\0';}IsAblosh = true;break;}}if(!IsAblosh){printf("\n\t用户%s不共享该文件,无需取消共享!", UserName);}else{Count++;printf("\n\t用户%s取消共享文件成功!", UserName);}break;}}}}}// 修改共享标志位if(Count != 0){IntToString(0, Read);DiskWrite(IdStPos+58, Read);printf("\n\t文件%s取消共享成功!", ASFile);}else{printf("\n\t当前所有用户均不共享该文件,无需取消共享!");}}getch();FMI();}///////////////////////////////////////////////////////////////////////////////int main(){FileManager FM;FM.UMI();system("pause");return 0;} 
0 0
原创粉丝点击