实验名称:同步与通信
1. 实验简介
本实验要求在模拟的I/O系统之上开发一个简单的文件系统。用户通过create, open, read, write, lseek, directory等命令与文件系统交互。文件系统把磁盘视为顺序编号的逻辑块序列,逻辑块的编号为0至L − 1。I/O系统利用内存中的数组模拟磁盘。
2. 总体设计
如上述,本实验要求在模拟的I/O系统之上开发一个简单的文件系统。故我们总体设计分为两大块:I/O系统与文件系统。
本次实验,我么只需模拟一个简单的I/O系统,使用数组ldisk[C][H][B]代替实际物理磁盘的真实结构。而,文件系统与I/O系统之间的接口主要功能是I/O系统从文件系统接收命令,将指定的数据流读或写到指定的磁盘块。
文件系统则是本次实验的重点,在文件系统中,我们需要设置有位图和问价描述符,反映磁盘的相关信息;同时,需设计一个且仅一个目录,记录文件系统下的所有文件。而,用户与文件系统之间的接口的主要功能是文件的创建、销毁、打开、关闭、读取、写入以及文件读写指针的移动和显示所有文件及其长度。
3. 模块设计
3.1. I/O系统模块
3.1.1. 模块功能
- I/O系统即输入输出系统,操作系统中负责管理输入输出设备的部分称为I/O系统,完成设备管理功能,包括外设编址,数据通路的建立,向主机提供外设的状态信息等。I/O系统的组成有:I/O设备,设备控制器及I/O操作有关的软硬件。
- 本实验中的I/O系统比较简单。I/O设备主要是指模拟的实际物理磁盘,I/O操作为对模拟的物理磁盘的存储块进行读写操作。
实际物理磁盘的结构是多维的:有柱面、磁头、扇区等概念。I/O系统的任务是隐藏磁盘的结构细节,把磁盘以逻辑块的面目呈现给文件系统。
逻辑块顺序编号,编号取值范围为0至L−1,其中L表示磁盘的存储块总数。实验中,我们可以利用数组ldisk[C][H][B]构建磁盘模型,其中CHB
分别表示柱面号,磁头号和扇区号。每个扇区大小为512字节。
3.1.2. 模块结构
该模块结构重点在于构建物理块的结构体。根据要求使用ldisk[C][H][B]构建磁盘模型,每一个物理块扇区大小为512字节,代码如下。
如果假设磁盘模型的C=8,H=8,B=8;则亦可使用ldisk[64][MaxLenth]构建物理块,直接将三维模型转换为一维模型。
typedef struct Block{
char Content[MaxLenth];//扇区大小为512字节
int LogicalBlockNum;//逻辑块号
int c;//柱面号
int h;//磁头号
int b;//扇区号
}BLOCK;
BLOCK ldisk[C][H][B];//磁盘模型
3.1.3. 模块接口
-
read_block(int i, char *p);
接口参数:i:逻辑块顺序编号为i;*p:指针所指向的内存位置
接口功能:该函数把逻辑块i的内容读入到指针p指向的内存位置,拷贝的字符个数为存储块的长度B。 -
write block(int i, char *p);
接口参数:i:逻辑块顺序编号为i;*p:指针所指向的内存位置
接口功能:该函数把指针p指向的内容写入逻辑块i,拷贝的字符个数为存储块的长度B。 -
此外,为了方便测试,我们还需要实现另外两个函数:一个用来把数组ldisk 存储到文件;另一个用来把文件内容恢复到数组。
3.1.4. 模块代码
read_block函数
void read_block(int i, char *p) {
for (int b = 0; b < blockLength; b++) {
*p = ldisk[i][b];
p++;
}
}
write_block函数
void write_block(int i, char *p) {
for (int b = 0; b < blockLength; b++) {
ldisk[i][b] = *p;
p++;
}
}
file_to_disk函数
void file_to_disk(string filename) {//从文件中读取数据到磁盘
ifstream in (filename);//以读的方式打开文件
if (!in.fail()) {
char block[blockLength];
for (int i = 0; i < L; i++) {
in.read(block, blockLength);
write_block(i, block);
}
in.close();
}
else{
cout<<"File Open Fail"<<endl;
}
}
disk_to_file函数
void disk_to_file(string filename){//将磁盘数据写入文件中
ifstream in (filename);//以读的方式打开文件
if (!in.fail()) {
char block[blockLength];
for (int i = 0; i < L; i++) {
read_block(i,block);
in.write(block, blockLength);
}
in.close();
}
else{
cout<<"File Open Fail"<&l