1、利用内存或外存存储结构实现文件系统的树型目录结构,并通过交互式命令完成文件与目录管理。
2、至少提供如下命令(大小写都能识别):MD(创建空目录)、CD(切换当前目录)、RD(删除空目录)、MK(创建文件)、DEL(删除文件)和D
1、本实验的完成可采用两种形式(两者只可选择一种):内存模拟,或外存文件模拟。内存模拟是指在程序中定义所有数据结构和文件系统的树型目录结构,这种形式易于实现,但是由于不进行磁盘文件操作,和真实的理论尚有很大差距。外存文件模拟是指在外存上创建一个模拟磁盘空间的文件(可简称“虚盘文件”),并把所有数据结构和树型目录建立在该文件中,这种形式实现复杂,但是更接近真实的文件管理。
2、参考FCB或i-node定义用于保存目录信息的数据结构:
l 如果采用内存模拟方式,在数据结构中不仅要定义文件或目录的常用属性,还需要定义用于实现树型目录结构所需的其它信息。可参考如下数据结构:
struct FCB{ //文件或目录控制块
char name[8];//文件或目录名
int size;//文件或目录大小,目录大小可设置为0
char type;//类型,1为文件,2为目录
char datetime[15]; //日期时间,格式为yyyymmdd hhmmss
struct FCB *next;//下一个兄弟节点
struct FCB *child;//第一个孩子节点
};
在程序启动时,可自动创建内存中的根目录节点。此后可利用交互命令继续创建子目录或文件。
l 如果采用外存文件模拟方式,则需要结合FAT或i-node在数据结构中考虑文件或目录的存储位置。同时还需解决虚盘文件的空闲空间管理、树型目录结构的表示等问题。可参考如下数据结构:
struct FCB{//文件或目录控制块
char name[8];//文件名最长不超过8个字符,这样整个FCB大小正好为32Byte
int size; //大小
int first_block; //第一块块号
char type; //类型,1为文件,2为目录,0为已删除目录项
char datetime[15]; //日期时间,格式为yyyymmdd hhmmss
};
定义两个宏:EMPTY_BLOCK和LAST_BLOCK,用于表示FAT16表中的特殊内容:
//代表某磁盘块为空块的FAT表项,长度为16bit
#define EMPTY_BLOCK 0x0000
//代表某磁盘块为文件或目录的最后一块的FAT表项,长度也为16bit
#define LAST_BLOCK 0xFFFF
IR(列出目录信息)。
实验代码 实验代码解释
关于显示TREE时的问题,可能不太像树,但是时间紧迫只能做到这个样子。
实验代码#include<iostream> #include<direct.h> using namespace std; struct FCB { char name[10]; // 文件名 char path[100]; // 路径位置 char parent[100]; // 父级 }; struct FCB fcb[50]; char position[100]="D:/"; int f = 0; // 创建目录 void MD() { cout<<position; string name; cin>>name; string temp; temp = position + name + "/"; mkdir(temp.c_str()); strcpy(fcb[f].name, name.c_str()); strcpy(fcb[f].path, temp.c_str()); strcpy(fcb[f].parent, position); f++; cout<<"创建成功"<<endl; } // 切换目录 void CD() { cout<<position<<"cd:"; string name; cin>>name; string temp = position + name + "/"; if (f == 0) { cout<<"当前没有目录可切换!!!\n"; } else { for (int i = 0; i < f; i++) { if (strcmp(fcb[i].path, temp.c_str()) == 0) { strcpy(position, fcb[i].path); cout<<"当前在"<<position<<"目录下\n"; break; } if (i == f) { cout<<"无此文件夹\n"; } } } } // 回根目录 void back_root() { strcpy(position, "D:/"); cout<<"当前在"<<position<<"目录下\n"; } // 删除目录 void RD() { cout<<position<<"rd:"; string name; cin>>name; string temp = position + name + "/"; int flag = f; int i; for (i = 0; i < f; i++) { if(strcmp(fcb[i].path, temp.c_str()) == 0) { for(int j = 0; j < f; j++) { if(strcmp(fcb[j].parent, fcb[i].path) == 0) { cout<<"此文件不能删除"<<endl; return; } } rmdir(temp.c_str()); f--; cout<<"删除成功\n"; break; } if (i == f) { cout<<"当前在"<<temp<<"目录下\n"; cout<<"无此文件\n"; return; } } for(int k = i; k < flag; k++) { fcb[k] = fcb[k+1]; } } // 显示 void show() { for(int i = 0; i < f; i++) { if((strcmp(fcb[i].parent, "D:/")) == 0) { cout<<fcb[i].name<<endl; } for(int j = 0; j < f; j++) { if(strcmp(fcb[j].parent, fcb[i].path) == 0) { cout<<"\t|___"<<fcb[j].name<<endl; } } } cout<<endl; } // 菜单 void menu() { cout<<"**************************\n"; cout<<"*\t1.创建目录\t *\n"; cout<<"*\t2.切换目录\t *\n"; cout<<"*\t3.回根目录\t *\n"; cout<<"*\t4.删除目录\t *\n"; cout<<"*\t5.显示TREE\t *\n"; cout<<"**************************\n"; } int main() { while(1) { menu(); int c; scanf("%d", &c); switch(c) { case 1: MD(); break; case 2: CD(); break; case 3: back_root(); break; case 4: RD(); break; case 5: show(); break; default: cout<<"无此选项!!!\n"; break; } } return 0; }