目录
一、实验目的
二、实验内容
三、实验要求
四、设计原理及相关算法
五、结果分析
1. 编译文件test08.cpp
2. format:格式化命令
3. mkdir hello:创建hello子目录
4. ls hello:显示hello目录下的信息
5. cd hello:进入hello目录
6. create world 100:创建新文件world
7. cp world hello:复制文件wold为文件hello
8. rename hello world2:重命名文件hello为world2
9. rm world:删除world文件
10. rmdir hello:删除hello目录
11. exit:退出该系统并保存消息
六、源代码
一、实验目的
1、探索、理解并掌握 FAT 文件系统的组织结构、设计原理和编程设计要旨。
2、通过实验,掌握 MSDOS 文件系统中文件目录管理的实现方法。
二、实验内容
1、设计并实现一个用于实现目录列表(类似 DOS 下的 DIR 命令或 Linux 的 Shell 命令 ls)的函数。
2、设计并实现一个用于实现文件更名的函数。
3、设计并实现一个用于实现文件删除的函数。
4*、设计并实现创建新目录、把现有的文件拷贝到新文件的函数。
这些函数的原型如下:
int fd_ls();
int fd_rename(char *oldfilename,char *newfilename);
int fd_rm(char *name);
int fd_mkdir(char *name);
int fd_cp(char *source, char *destination);
三、实验要求
本实验在 MSDOS 格式的软盘上完成。要实现这些函数需要一个使物理磁盘准备的函数(该函 数调用磁盘驱动程序的初始化代码以及选择的其他初始化代码来判断磁盘几何结构): int fd_load(char driveLetter); 文件的更名与删除,需要查找文件,文件删除还要遍历 FAT 中的链接,设置 FAT 中每个簇项并将其标记为未使用,更新目录项。在删除的情况中,要注意文件的隐藏、只读和系统属性。任何具有这种属性的文件都不能删除。
此外,任务 4 中还需要 fd_open()、fd_close()、fd_read()、fd_write()函数实现字节流的写。
四、设计原理及相关算法
想要完成操作系统算法,首先要弄清楚操作系统相关的专业术语。弄清各个算法的流程和目的要求。才能模拟出相关算法的过程。
一般情况下,操作系统中,文件管理提供了如下功能:
①统一管理文件存储空间(即外存),实施存储空间的分配与回收。
②确定文件信息的存放位置及存放形式。
③实现文件从名字空间到外存地址空间的映射,即实现文件的按名存取。
④有效实现对文件的各种控制操作(如建立、撤销、打开、关闭文件等)和存取操作(如读、写、修改、复制、转储等)
其实就是对文件进行管理。
本次实验对文件定义了如下数据结构:
class file:
def __init__(self, uid, fid, name, status):
self.uid = uid
self.fid = fid
self.name = name
self.status = status
定义了文件的id标识,文件名,状态等等。
五、结果分析
1. 编译文件test08.cpp
g++ test08.cpp -o test08
1、设计并实现一个用于实现目录列表(类似 DOS 下的 DIR 命令或 Linux 的 Shell 命令 ls)的函数。
2、设计并实现一个用于实现文件更名的函数。
3、设计并实现一个用于实现文件删除的函数。
4*、设计并实现创建新目录、把现有的文件拷贝到新文件的函数。
这些函数的原型如下:
int fd_ls();
int fd_rename(char *oldfilename,char *newfilename);
int fd_rm(char *name);
int fd_mkdir(char *name);
int fd_cp(char *source, char *destination);
本实验在 MSDOS 格式的软盘上完成。要实现这些函数需要一个使物理磁盘准备的函数(该函 数调用磁盘驱动程序的初始化代码以及选择的其他初始化代码来判断磁盘几何结构): int fd_load(char driveLetter); 文件的更名与删除,需要查找文件,文件删除还要遍历 FAT 中的链接,设置 FAT 中每个簇项并将其标记为未使用,更新目录项。在删除的情况中,要注意文件的隐藏、只读和系统属性。任何具有这种属性的文件都不能删除。
此外,任务 4 中还需要 fd_open()、fd_close()、fd_read()、fd_write()函数实现字节流的写。
四、设计原理及相关算法
想要完成操作系统算法,首先要弄清楚操作系统相关的专业术语。弄清各个算法的流程和目的要求。才能模拟出相关算法的过程。
一般情况下,操作系统中,文件管理提供了如下功能:
①统一管理文件存储空间(即外存),实施存储空间的分配与回收。
②确定文件信息的存放位置及存放形式。
③实现文件从名字空间到外存地址空间的映射,即实现文件的按名存取。
④有效实现对文件的各种控制操作(如建立、撤销、打开、关闭文件等)和存取操作(如读、写、修改、复制、转储等)
其实就是对文件进行管理。
本次实验对文件定义了如下数据结构:
class file:
def __init__(self, uid, fid, name, status):
self.uid = uid
self.fid = fid
self.name = name
self.status = status
定义了文件的id标识,文件名,状态等等。
五、结果分析
1. 编译文件test08.cpp
g++ test08.cpp -o test08
想要完成操作系统算法,首先要弄清楚操作系统相关的专业术语。弄清各个算法的流程和目的要求。才能模拟出相关算法的过程。
一般情况下,操作系统中,文件管理提供了如下功能:
①统一管理文件存储空间(即外存),实施存储空间的分配与回收。
②确定文件信息的存放位置及存放形式。
③实现文件从名字空间到外存地址空间的映射,即实现文件的按名存取。
④有效实现对文件的各种控制操作(如建立、撤销、打开、关闭文件等)和存取操作(如读、写、修改、复制、转储等)
其实就是对文件进行管理。
本次实验对文件定义了如下数据结构:
class file:
def __init__(self, uid, fid, name, status):
self.uid = uid
self.fid = fid
self.name = name
self.status = status
定义了文件的id标识,文件名,状态等等。
1. 编译文件test08.cpp
g++ test08.cpp -o test08
2. format:格式化命令
3. mkdir hello:创建hello子目录
4. ls hello:显示hello目录下的信息
5. cd hello:进入hello目录
6. create world 100:创建新文件world
7. cp world hello:复制文件wold为文件hello
8. rename hello world2:重命名文件hello为world2
6. create world 100:创建新文件world
7. cp world hello:复制文件wold为文件hello
8. rename hello world2:重命名文件hello为world2
8. rename hello world2:重命名文件hello为world2
9. rm world:删除world文件
10. rmdir hello:删除hello目录
11. exit:退出该系统并保存消息
11. exit:退出该系统并保存消息
六、源代码
创建文件test08.cpp
vim test08.cpp g++ test08.cpp -o test08
#include#include #include #include #include #include using namespace std; const int BLOCKNUM_SIZE=2; //盘块号大小 const int BLOCK_SIZE=1024; //一个盘块大小数 const int BLOCK_NUM=10001; //盘块数量 const int DISK_SIZE=1024*1000*10; //磁盘大小 const int LIST_SIZE=32; //目录项大小 const int MAP_SIZE=10001; //MAP 长度 const int FATNUM=125; //FAT的盘块数 第块没有用 const int FATLIST=512; //每个盘口FAT的记录数 const int DATABEG=128; //数据项开始FAT号 struct FCB{ char fname[8]; //文件名 char exname[3]; //扩展名 short fnum; //首块号 int length; //文件大小, 目录则文件大小为; }; struct fatid{ short id[FATNUM*FATLIST]; //FAT 大小512个记录 一块 }*FAT; struct map{ bitset maplist; }*MAP; struct DIR{ struct FCB list[LIST_SIZE+1]; }*filedir; int currentid=128; //当前FAT号 int currentdir=128; //当前目录块号初始化是+1 由于第个单元没有使用 char *file; //磁盘的首地址 char *FilePath="myfat"; //window文件保存地址 FILE *fp; //window 文件地址 string CURRENT="root\"; //当前路径 char cmd[30]; //输入指令 char command[16]; void init(struct fatid *FAT){ int i,j; for(i=1;i DATABEG) FAT->id[i]=0; else FAT->id[i]=-1; } } void format(){ bool i; FAT=(struct fatid *)(file+BLOCK_SIZE); //当前FAT地址 MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE); //初始化位示图 init(FAT); FAT->id[0]=9872; filedir=(struct DIR *)(file+(FATNUM+1+2)*BLOCK_SIZE); //当前目录指针地址 FAT->id[128]=-1; FAT->id[0]=9872-1; strcpy(filedir->list[0].fname,"."); strcpy(filedir->list[0].exname,"dir"); filedir->list[0].fnum=currentdir; filedir->list[0].length=0; strcpy(filedir->list[1].fname,".."); strcpy(filedir->list[1].exname,"dir"); filedir->list[1].fnum=currentdir; filedir->list[1].length=0; fp=fopen(FilePath,"w+"); fwrite(file,sizeof(char),DISK_SIZE,fp); fclose(fp); printf("初始化已经完成,现在可以进行操作了!nn"); } int mkdir(char *str) { int i,j; int blockid; //将要创建的FAT号 int blockdir; //将要创建的目录块号 int listnum; //目录块内编号 struct fatid *flagid; struct DIR *dir; //当前目录指针 struct map *MAP; struct fatid *FAT; if(strcmp(str,"")==0) { printf("目录名称不能为空n"); return 0; } dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE); MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE); FAT=(struct fatid *)(file+BLOCK_SIZE); for(i=DATABEG+1;i maplist[i]==0) break; } if(i>BLOCK_NUM) { printf("内存不足n"); return 0; } MAP->maplist[i]=1; //map 置即已用 dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE); for(i=2;i list[i].fname,str)==0) { printf("目录下有同名文件夹n"); return 0; } } for(i=2;i list[i].fname,"")==0) //有空的目录块且无重名,第一版本的时候与上面的循环放在一起,存在一个情况是前面的建立的目录删除后,直接被同名的覆盖了 break; if(i>LIST_SIZE) { printf("内存不足n"); return 0; } } flagid=(struct fatid *)(file+BLOCK_SIZE); //fat 首位地址 for(j=DATABEG+1;j id[j]==0) { blockdir=j; break; } } strcpy(dir->list[i].fname,str); dir->list[i].fnum=blockdir; strcpy(dir->list[i].exname,"dir"); dir->list[i].length=0; dir=(struct DIR *)(file+blockdir*BLOCK_SIZE); //为新目录项创建根目录 strcpy(dir->list[0].fname,"."); strcpy(dir->list[0].exname,"dir"); dir->list[0].fnum=blockdir; dir->list[0].length=0; strcpy(dir->list[1].fname,".."); strcpy(dir->list[1].exname,"dir"); dir->list[1].fnum=currentdir; dir->list[1].length=0; flagid->id[j]=-1; //修改FAT 目录尾部 FAT->id[0]=FAT->id[0]-1; printf("已经成功创建目录%s n",str); return 0; } int listshow() { int i,sumfile,sumdir,fl[100],dr[100];//fl 为文件的号数,dr为目录的号数 sumfile=sumdir=0; struct DIR *dir; struct fatid *FAT; dir=(struct DIR *)(file+currentdir*BLOCK_SIZE); for(i=0;i list[i].length==0&&(strcmp(dir->list[i].fname,"")!=0)&&(dir->list[i].fnum!=0)) //为目录的 { dr[sumdir]=i; sumdir++; } if(dir->list[i].length!=0&&strcmp(dir->list[i].fname,"")!=0) //为目录的 { fl[sumfile]=i; sumfile++; } } for(i=0;i list[dr[i]].fname); for(i=0;i list[fl[i]].fname,dir->list[fl[i]].exname); printf("n"); printf("n在该目录下共有%d 个文件, %d 个文件夹nn",sumfile,sumdir-2); return 0; } int rmdir(char *str) { int i; int blockid; int flag=0; //FAT号 int blocknum; //目录块 struct fatid *FAT; struct DIR *dir; struct DIR *flagdir; //标记目录块 char c='a'; //做用户交互 int m=2; //从第三个子目录项开始搜索要删除的目录项情况 FAT=(struct fatid *)(file+BLOCK_SIZE); dir=(struct DIR *)(file+currentdir*BLOCK_SIZE); //当前目录指针 MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE); for(i=2;i list[i].fname,str)==0) //找到要删除的子目录 { break; } } if(i>LIST_SIZE) { printf("该文件夹下不存在%s",str); return 0; } while(1) { printf("是否确认?(Y/N)"); cin>>c; if((c=='y'||c=='Y')||(c=='n'||c=='N')) break; } if(c=='n'||c=='N') return 0; blocknum=dir->list[i].fnum; flagdir=(struct DIR *)(file+blocknum*BLOCK_SIZE); while(m!=LIST_SIZE) { if(strcmp(flagdir->list[m].fname,"")!=0) { printf("该目录下有子文件或者子目录,不能删除该目录"); } m++; } strcpy(dir->list[i].fname,""); //父目录DIR strcpy(dir->list[i].exname,""); dir->list[i].fnum=0; strcpy(flagdir->list[0].fname,""); //要删除目录的DIR strcpy(flagdir->list[0].exname,""); flagdir->list[0].fnum=0; strcpy(flagdir->list[1].fname,""); strcpy(flagdir->list[1].exname,""); flagdir->list[0].fnum=0; MAP->maplist[blocknum]=0; FAT->id[blocknum]=0; FAT->id[0]=FAT->id[0]+1; return 0; } int changedir(char *str) { int i,j; int blocknum; //当前目录位置 int flagnum; //temp的目录位置 struct DIR * flagdir,*dir; struct fatid * FAT; string strflag; //为了改当前显示的代码 dir=(struct DIR *)(file+currentdir*BLOCK_SIZE); if(strcmp("..",str)==0) //判断是不是上层目录 { blocknum=currentdir; if(dir->list[0].fnum==dir->list[1].fnum) //根目录的特征 { return 1; } currentdir=dir->list[1].fnum; //改变当前目录指针 flagdir=(struct DIR *)(file+currentdir*BLOCK_SIZE); //去上层的目录地址 for(int j=0;j list[j].fnum==blocknum) { strflag=flagdir->list[j].fname; break; } } CURRENT=CURRENT.substr(0,(CURRENT.length()-strflag.length())-1); return 1; } for(i=2;i list[i].fname,str)==0&&strcmp(dir->list[i].exname,"dir")==0) { currentdir=dir->list[i].fnum; break; } } if(i>LIST_SIZE) { printf("找不到指定的目录%sn",str); return 0; } CURRENT=CURRENT+str+"\"; return 1; } int create(char *str,int length) { //getfilename int i,j,l,t,k; int blockdir; int fid; //FAT的首块号 int flag; //文件的首块判断 char name[8]={0}; //文件名称 char exname[3]={0}; //文件扩展名 int templength; //temp文件长度 struct fatid * FAT; struct DIR *dir; struct map *MAP; dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE); MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE); FAT=(struct fatid *)(file+BLOCK_SIZE); templength=length; l=strlen(str); //取文件名 for(i=0;i =8) { printf("文件名称过长n"); return 0; } //去扩展名 j=0; i++; i++;//除去点 k=l-i; for(j=0;j


