2022年2022年简单文件系统实现 3.pdf
#include #include #include #include using namespace std; #define GENERAL 1/1 代表普通文件2 代表目录文件0 表示空文件#define DIRECTORY 2 #define Zero 0 struct FCB char fname16; / 文件名char type; / 0 空文件1 目录文件2 空文件int size; / 文件大小int fatherBlockNum; / 当前的父目录盘块号int currentBlockNum; / 当前的盘块void initialize() strcpy(fname,0); type = Zero; size =0; fatherBlockNum = currentBlockNum = 0; ; const char* FilePath = C:myfiles;/*常量设置 */ const int BlockSize = 512; / 盘块大小const int OPEN_MAX = 5; / 能打开最多的文件数const int BlockCount = 128; / 盘块数const int DiskSize = BlockSize * BlockCount; / 磁盘大小 64K const int FcbCount = BlockSize/sizeof(FCB);/目录文件的最多FCB数int OpenFileCount = 0; / 统计当前打开文件数目struct OPENLIST / 用户文件打开表 int files; / 当前打开文件数FCB fOPEN_MAX; /FCB 拷贝OPENLIST() files=0; for(int i=0;iOPEN_MAX;i+) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 15 页 - - - - - - - - - fi.fatherBlockNum = -1;/为分配打开fi.type=GENERAL; ; struct dirFile/*-目录文件结构 -*/ struct FCB fcbFcbCount; void init(int _FatherBlockNum,int _CurrentBlockNum,char *name)/父块号,当前块号,目录名 strcpy(fcb0.fname,name); /本身的 FCB fcb0.fatherBlockNum=_FatherBlockNum; fcb0.currentBlockNum=_CurrentBlockNum; fcb0.type=DIRECTORY; / 标记目录文件for(int i=1;iformat();/ 打开文件列表初始化delete openlist; openlist=new OPENLIST; /*- 保存到磁盘上myfiles-*/ fp = fopen(FilePath,w+); fwrite(BaseAddr,sizeof(char),DiskSize,fp); fclose(fp); printf( 格式化成功!n); return 1; int mkdir(char *sonfname)/*-创建子目录 -*/ / 判断是否有重名、 寻找空白子目录项、 寻找空白盘块号、 当前目录下增加该子目录项、分配子目录盘块并且初始化、修改fat 表int i,temp,iFAT; struct dirFile *dir; / 当前目录的指针if(current = 2) / 根目录dir=&(osPoint-root); else dir=(struct dirFile *)(osPoint-datacurrent-3); /*- 为了避免该目录下同名文件夹-*/ 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 15 页 - - - - - - - - - for(i = 1;ifcbi.type=DIRECTORY & strcmp(dir-fcbi.fname,sonfname)=0 ) printf( 该文件夹下已经有同名的文件夹存在了!n); return 0; for(i = 1;i fcbi.type=Zero) break; if(i = FcbCount) printf( 该目录已满 !请选择新的目录下创建!n); return 0; temp = i; for(i = 3;i FAT1i = 0) break; if(i = BlockCount) printf( 磁盘已满 !n); return 0; iFAT=i; /*- 接下来进行分配-*/ osPoint-FAT1iFAT=osPoint-FAT2iFAT = 2; /2 表示分配给下级目录文件/ 填写该分派新的盘块的参数strcpy(dir-fcbtemp.fname,sonfname); dir-fcbtemp.type=DIRECTORY; dir-fcbtemp.fatherBlockNum=current; dir-fcbtemp.currentBlockNum=iFAT; / 初始化子目录文件盘块dir=(struct dirFile*)(osPoint-data iFAT-3); / 定位到子目录盘块号dir-init (current,iFAT,sonfname);/iFAT 是要分配的块号,这里的current 用来指要分配的块的父块号printf( 创建子目录成功!n); return 1; int rmdir(char *sonfname)/*-删除当前目录下的文件夹-*/ 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 15 页 - - - - - - - - - int i,temp,j;/ 确保当前目录下有该文件,并记录下该FCB下标struct dirFile *dir; / 当前目录的指针if(current=2) dir=&(osPoint-root); else dir=(struct dirFile *)(osPoint-data current-3); for(i=1;ifcbi.type=DIRECTORY & strcmp(dir-fcbi.fname,sonfname)=0) break; temp=i; if(i=FcbCount) printf( 当前目录下不存在该子目录!n); return 0; j = dir-fcbtemp.currentBlockNum; struct dirFile *sonDir; / 当前子目录的指针sonDir=(struct dirFile *)(osPoint-data j - 3); for(i=1;ifcbi.type!=Zero) printf( 该文件夹为非空文件夹,为确保安全,请清空后再删除!n); return 0; /* 开始删除子目录操作*/ osPoint-FAT1j = osPoint-FAT2j=0; /fat 清空char *p=osPoint-dataj-3; / 格式化子目录memset(p,0,BlockSize); dir-fcbtemp.initialize(); / 回收子目录占据目录项printf( 删除当前目录下的文件夹成功n); return 1; /*- 在当前目录下创建文本文件-*/ int create(char *name) int i,iFAT;/temp, int emptyNum = 0, isFound = 0; / 空闲目录项个数struct dirFile *dir; / 当前目录的指针名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 15 页 - - - - - - - - - if(current=2) dir=&(osPoint-root); else dir=(struct dirFile *)(osPoint-data current-3); for(i=1;ifcbi.type = Zero & isFound = 0) emptyNum = i; isFound = 1; else if(dir-fcbi.type=GENERAL & strcmp(dir-fcbi.fname,name)=0 ) printf( 无法在同一目录下创建同名文件!n); return 0; if(emptyNum = 0) printf( 已经达到目录项容纳上限,无法创建新目录!n); return 0; for(i = 3;iFAT1i=0) break; if(i=BlockCount) printf( 磁盘已满 !n); return 0; iFAT=i; /*- 进入分配阶段-*/ 分配磁盘块osPoint-FAT1iFAT = osPoint-FAT2iFAT = 1; /*- 接下来进行分配-*/填写该分派新的盘块的参数strcpy(dir-fcbemptyNum.fname,name); dir-fcbemptyNum.type=GENERAL; dir-fcbemptyNum.fatherBlockNum=current; dir-fcbemptyNum.currentBlockNum=iFAT; dir-fcbemptyNum.size =0; char* p = osPoint-dataiFAT -3; memset(p,0,BlockSize); printf( 在当前目录下创建文本文件成功!n); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 15 页 - - - - - - - - - return 1; /*- 查询子目录 -*/ int listshow() int i,DirCount=0,FileCount=0; / 搜索当前目录struct dirFile *dir; / 当前目录的指针if(current=2) dir=&(osPoint-root); else dir=(struct dirFile *)(osPoint-data current-3); for(i=1;ifcbi.type=GENERAL) / 查找普通文件FileCount+; printf(%s 文本文件 .n,dir-fcbi.fname); if(dir-fcbi.type=DIRECTORY) / 查找目录文件DirCount+; printf(%s 文件夹 .n,dir-fcbi.fname); printf(n该目录下共有%d 个文本文件 , %d 个文件夹 nn,FileCount,DirCount); return 1; /*- 在当前目录下删除文件-*/ int delfile(char *name) int i,temp,j; / 确保当前目录下有该文件,并且记录下它的FCB下标struct dirFile *dir; / 当前目录的指针if(current = 2) dir=&(osPoint-root); else dir=(struct dirFile *)(osPoint-data current-3); for(i=1;i fcbi.type=GENERAL & strcmp(dir-fcbi.fname,name)=0) break; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 15 页 - - - - - - - - - if(i = FcbCount) printf( 当前目录下不存在该文件!n); return 0; int k; for(k=0;kf k.type = GENERAL)& (strcmp(openlist-f k.fname,name)=0) if(openlist-fk.fatherBlockNum = current) break; else printf( 该文件未在当前目录下!n); return 0; if(k!=OPEN_MAX) close(name); / 从打开列表中删除/* 开始删除文件操作*/ temp=i; j = dir-fcb temp.currentBlockNum ; / 查找盘块号j osPoint-FAT1j=osPoint-FAT2j=0; /fat1,fat2表标记为空白char *p=osPoint-dataj - 3; memset(p,0,BlockSize); / 清除原文本文件的内容dir-fcbtemp.initialize(); /type=0; / 标记该目录项为空文件printf( 在当前目录下删除文件成功!n); return 1; /*- 进入当前目录下的子目录-*/ int changePath(char *sonfname) struct dirFile *dir; / 当前目录的指针if(current=2) dir=&(osPoint-root); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 15 页 - - - - - - - - - else dir=(struct dirFile *)(osPoint-data current-3); /* 回到父目录 */ if(strcmp(sonfname,.)=0) if(current=2) printf( 你现已经在根目录下!n); return 0; current = dir-fcb0.fatherBlockNum ; currentPath = currentPath.substr(0,currentPath.size() - strlen(dir-fcb0.fname )-1); return 1; /* 进入子目录 */ / 确保当前目录下有该目录,并且记录下它的FCB下标int i,temp; for(i = 1; i fcbi.type=DIRECTORY&strcmp(dir-fcbi.fname,sonfname)=0) temp=i; break; if(i=FcbCount) printf( 不存在该目录!n); return 0; / 修改当前文件信息current=dir-fcb temp.currentBlockNum ; currentPath = currentPath+dir-fcb temp.fname +; printf( 进入当前目录下的子目录成功!n); return 1; int exit() / 保存到磁盘上C:myfiles / 将所有文件都关闭/*-System exit-*/ fp=fopen(FilePath,w+); fwrite(BaseAddr,sizeof(char),DiskSize,fp); fclose(fp); / 释放内存上的虚拟磁盘free(osPoint); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 15 页 - - - - - - - - - / 释放用户打开文件表delete openlist; printf( 退出文件系统成功!nn); return 1; int write(char *name)/*-在指定的文件里记录信息-*/ int i; char *startPoint,*endPoint; / 在打开文件列表中查找file(还需要考虑同名不同目录文件的情况!) for(i=0;if i.fname,name)=0 ) if(openlist-fi.fatherBlockNum =current) break; else printf( 该文件处于打开列表中,本系统只能改写当前目录下文件!n); return 0; if(i=OPEN_MAX) printf( 该文件尚未打开,请先打开后写入信息!n); return 0; int active=i; int fileStartNum = openlist-factive.currentBlockNum - 3 ; startPoint = osPoint-datafileStartNum; endPoint = osPoint-datafileStartNum + 1; printf( 请输入文本以Ctrl D 号结束 :t); char input; while(input=getchar()!=4) if(startPoint endPoint-1) *startPoint+ = input; else printf( 达到单体文件最大容量!); *startPoint+ = 4; break; return 1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 15 页 - - - - - - - - - int read(char *file)/*-选择一个打开的文件读取信息-*/ int i,fileStartNum; char *startPoint,*endPoint; /struct dirFile *dir; / 在打开文件列表中查找file(还需要考虑同名不同目录文件的情况!) for(i=0;if i.fname,file)=0 ) if(openlist-fi.fatherBlockNum =current) break; else printf( 该文件处于打开列表中,本系统只能阅读当前目录下文件!n); return 0; if(i=OPEN_MAX) printf( 该文件尚未打开,请先打开后读取信息!n); return 0; int active=i;/ 计算文件物理地址fileStartNum = openlist-factive.currentBlockNum - 3 ; startPoint = osPoint-datafileStartNum; endPoint = osPoint-datafileStartNum + 1; printf( 该文件的内容为: ); while(*startPoint)!=4& (startPoint endPoint) putchar(*startPoint+); printf(n); return 1; int open(char *file)/打开文件/* 当前目录下添加一个打开文件*/ int i,FcbIndex; / 确保没有打开过该文件= 相同名字+ 相同目录for(i=0;ifi.type =GENERAL & strcmp(openlist-f i.fname,file)=0 &openlist-fi.fatherBlockNum = current) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 15 页 - - - - - - - - - printf( 该文件已经被打开!n); return 0; / 确保有空的打开文件项if(openlist-files = OPEN_MAX) printf( 打开文件数目达到上限!无法再打开新文件.n); return 0; / 确保当前目录下有该文件,并且记录下它的FCB下标struct dirFile *dir; / 当前目录的指针if(current=2) dir=&(osPoint-root); else dir=(struct dirFile *)(osPoint-data current-3); for(i = 1;ifcbi.type=GENERAL & strcmp(dir-fcbi.fname,file)=0 ) FcbIndex=i; break; if(i=FcbCount) printf( 当前目录下不存在该文件!n); return 0; / 装载新文件进入打开文件列表,(FCB信息,文件数 +) openlist-fOpenFileCount = dir-fcbFcbIndex; /FCB拷贝openlist-files +; printf( 文件打开成功 !n); OpenFileCount+; return 1; int close(char *file) / 释放该文件所占内存/ 释放用户打开文件列表表项int i; / 在打开文件列表中查找file(还需要考虑同名不同目录文件的情况!) for(i=0;if i.type = GENERAL)& 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 15 页 - - - - - - - - - (strcmp(openlist-f i.fname,file)=0) if(openlist-fi.fatherBlockNum = current) break; else printf( 该文件已打开,但未在当前目录下,无法关闭!n); return 0; if(i=OPEN_MAX) printf( 该文件未在打开列表中!n); return 0; int active=i; openlist-files -; openlist-factive.initialize(); OpenFileCount-; printf( 该文件已关闭 !n); return 1; int main() printf(t*My Filesys(FAT)*nn); printf(t* n); printf(t* format :对磁盘格式化. * n); printf(t* mkdir dirname : 创建子目录 . * n); printf(t* rmdir dirname : 删除子目录 . * n); printf(t* ls dirname : 显示当前目录下信息. * n); printf(t* cd dirname :切换当前目录. * n); printf(t* create filename :创建一个新文件. * n); printf(t* open filename :打开文件 . * n); printf(t* write filename :选择一个打开的文件写入信息* n); printf(t* read filename : 选择一个打开的文件读取信息. * n); printf(t* rm filename :删除文件 . * n); printf(t* close filename :关闭文件 . * n); printf(t* exit :安全退出该文件系统,保存信息 . * n); printf(t*nn); openlist=new OPENLIST;/创建用户文件打开表名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 15 页 - - - - - - - - - BaseAddr=(char *)malloc(DiskSize);/ 申请虚拟空间osPoint=(struct DISK *)(BaseAddr);/ 虚拟磁盘初始化if(fp=fopen(FilePath,r)!=NULL)/加载磁盘文件fread(BaseAddr,sizeof(char),DiskSize,fp); printf( 加载磁盘文件( %s )成功 ,现在可以进行操作了!nn,FilePath); else printf( 这是你第一次使用该文件管理系统!t 正在初始化 .n); format(); printf( 初始化已经完成,现在可以进行操作了!nn); while(1) coutcmd; if(cmd=format) format(); else if(cmd=mkdir) cincommand; mkdir(command); else if(cmd=rmdir) cincommand; rmdir(command); else if(cmd=ls) listshow(); else if(cmd=cd) cincommand; changePath(command); else if(cmd=create) cincommand; create(command); else if(cmd=write) cincommand; write(command); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 15 页 - - - - - - - - - else if(cmd=read) cincommand; read(command); else if(cmd=rm) cincommand; delfile(command); else if(cmd=open) cincommand; open(command); else if(cmd=close) cincommand; close(command); else if(cmd=exit) exit(); break; else cout无效指令 ,请重新输入 :endl; printf(Thank you for using my file system!n); return 1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 15 页 - - - - - - - - -