Advertisement

操作系统lab5实验报告

阅读量:

安全1601_沈香港_16281077_操作系统lab5

  • 实验介绍
      • 整体组织
      • 文件描述符
      • 目录项
      • 总结:
    • ①对磁盘的操作:

    • ②对文件的操作:

    • 实验过程

实验介绍

本实验要求在假设的I/O 系统之上开发一个简单的文件系统,这样做既能让实验者对文件系统有整体了解,又避免了涉及过多细节。用户通过create, open, read 等命令与文件系统交互。文件系统把磁盘视为顺序编号的逻辑块序列,逻辑块的编号为0 至L-1。I/O 系统利用内存中的数组模拟磁盘。
实际物理磁盘的结构是多维的:有柱面、磁道、扇区等概念。I/O 系统的任务是隐藏磁盘的结构细节,把磁盘以逻辑块的面目呈现给文件系统。逻辑块顺序编号,编号取值范围为0 至L -1,其中L 表示磁盘的存储块总数。实验中,我们可以利用字符数组ldisk[C][H][B] 构建磁盘模型,其中B 表示每个存储块的长度。I/O 系统从文件系统接收命令,根据命令指定的逻辑块号把磁盘块的内容读入命令指定的内存区域,或者把命令指定的内存区域内容写入磁盘块。内存区域内容写入磁盘块。

整体组织

注:我定义的文件系统中,磁盘分为两大部分:数据区和保留区。其中保留区中又包含位图区和文件描述符区,数据区的首部是文件的目录项,也就是说,文件的目录项在文件创建时会创建相应的目录项在数据区的文件首部;而位图区用于表征数据的占用情况,例如数据区的第N块被分配了,那么位图区中也要做相应的改变。

文件描述符

注:文件描述符位于保留区后半部,用于分为两类型,即表示目录的0号描述符和1号以后的描述符,用于表示文件的长度和分配块情况,具体看上图。

目录项

注:目录项位于数据区的首部,目录项的0位用于保存文件描述符的序号,1号以后用于存放文件名

总结:

一个文件的所有存放于由位视图,文件描述符,目录项和数据区表征。

①对磁盘的操作:

字符数组(L*B)模拟磁盘,考虑到文件系统和I/O系统(磁盘)不是同一层,故将所有对磁盘的操作只能规约为这二者之间的接口来操作:

复制代码
    void read_block(int,char *);			//文件系统与IO设备的接口函数,读取块
    void write_block(int,char *);			//文件系统与IO设备的接口函数,写入块
    
    
      
      
    

(代码详见源文件)
也就是说,之后的文件的创建,删除,打开,关闭,指针定位等操作,里面牵扯到磁盘内容读写的步骤,全部需要用这两个接口完成,然后这两个接口对磁盘的操作是以块为单位的,所以例如某些操作,只要更改磁盘中的某一块中的某一位,则需要先读取某一块存于零时数组中,然后修改这个数组的某一位,然后再将这个数组写回磁盘。

②对文件的操作:

复制代码
    文件的创建int create(char *)
    
    
      
    

.找一空闲文件描述符
.在文件目录里为新创建的文件分配一个目录项,(可能需要为目录文件分配新的磁盘块)
.在分配到的目录项里记录文件名以及描述符编号
.返回状态信息

复制代码
    文件的删除int destroy(char *)
    
    
      
    

.在目录里搜索该文件的描述符编号
.删除该文件对应的目录项,并更新位图
.释放文件描述符
.返回状态信息

复制代码
    文件的打开int open(char *)
    
    
      
    

.搜索目录找到文件对应的描述符序号
.在打开文件表中分配一个表目
.在分配到的表目中把读写指针置为0,并记录描述符编号
.读入文件的第一块到读写缓冲区中
.返回分配到的表目在打开文件表中的索引号

复制代码
    文件的关闭int close(int)
    
    
      
    

.把缓冲区的内容写入磁盘
.释放该文件再打开文件表中对应的表目
.返回状态信息

复制代码
    文件的写int write(int,int,int)
    
    
      
    

.写的内容若小于缓冲区内容,则直接写入缓冲区,完成写操作(关闭的时候会将缓冲区写入文件)
.入写入的内容,缓冲区无法一次装完,则需要填满缓冲区,然后将缓冲区写入文件,腾出缓冲区,然后再写入缓冲区,碰到缓冲区满的情况便写入文件,腾出缓冲区,以 便文件的写入,完成写操作。
.返回状态信息

复制代码
    文件的读int read(int,int,int)
    
    
      
    

.将文件整个内容整个取出在一个临时字符数组中
.根据要求的读取参数定位读写位置,输出读取内容,完成读操作
.返回状态信息

复制代码
     文件指针定位int lseek(int,int)
    
    
      
    

.把文件的读写指针移动到pos 指定的位置。pos
.是一个整数,表示从文件开始位置的偏移量。文件打开时,读写指针
.自动设置为0。每次读写操作之后,它指向最后被访问的字节的下一
.个位置。lseek 能够在不进行读写操作的情况下改变读写指针能位置。

实验过程

复制代码
    该文件系统根据输入的指令来对文件系统的操作
    
    
      
    

在这里插入图片描述
此时该文件系统会初始化
新建文件操作:(create)
在这里插入图片描述
显示目录文件:(dir)
在这里插入图片描述
文件的删除:delete
在这里插入图片描述
打开文件:(open)
在这里插入图片描述
打开文件表:(oplist)

文件的写操作:(write)
在这里插入图片描述
关闭文件:close
在这里插入图片描述
打开和读取lmjorz:
在这里插入图片描述
后台查看磁盘数组的内容,可以查看实时情况命令(ldisk)
在这里插入图片描述
实验源代码:

operation.h

复制代码
    //#pragma warning( disable : 4996)
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int show_openlist();
    void directory();
    void show_help();
    void show_ldisk();
    
    //核心函数
    void read_block(int, char *);
    void write_block(int, char *);
    void Init();
    int create(char *);
    int destroy(char *);
    int open(char *);
    int close(int);
    int read(int, int, int);
    int write(int, int, int);
    int write_buffer(int, int);
    int lseek(int, int);
    void Init_block(char, int);
    
    /*****************************************************/
    /*****************************************************/
    
    void read_block(int i, char *p)
    /**************************读磁盘块
    该函数把逻辑块的内容读入到指针指向的内存位置
    拷贝的字符个数为存储块的长度。
    ***************************/
    {
     char * temp = (char *)malloc(sizeof(char));
     temp = p;
     for (int a = 0; a < B;)
     {
     	*temp = ldisk[i][a];
     	a++;
     	temp++;
     }
    }
    
    void write_block(int i, char *p)
    /**************************写磁盘块
    该函数把指针p指向的内容写入逻辑块i
    拷贝的字符个数为a存储块的长度。
    ***************************/
    {
     char * temp = (char *)malloc(sizeof(char));
     temp = p;
     for (int a = 0; a < B;)
     {
     	ldisk[i][a] = *temp;
     	a++;
     	temp++;
     }
    }
    
    void Init_block(char *temp, int length)
    /**************************初始化一个字符数组块
    处理的字符数组块长度为a
    内容为'\0'
    ***************************/
    {
     int i;
     for (i = 0; i < length; i++)
     {
     	temp[i] = '\0';
     }
    }
    
    int write_buffer(int index, int list)
    {
    
     int i;
     int j;
     int freed;
     char temp[B];
    
     int buffer_length = BUFFER_LENGTH;
     for (i = 0; i < BUFFER_LENGTH; i++)
     {
     	if (open_list[list].buffer[i] == '\0')
     	{
     		buffer_length = i;
     		break;
     	}
     }
    
     int x = open_list[list].pointer[0];
     int y = open_list[list].pointer[1];
     int z = B - y;
    
    
     if (buffer_length < z) {
     	read_block(x, temp);
     	strncat_s(temp + y,sizeof(temp + y+ buffer_length), open_list[list].buffer, buffer_length);
     	write_block(x, temp);
    
     	read_block(index + FILE_SIGN_AREA, temp);
    
     	temp[1] += buffer_length;
    
     	write_block(index + FILE_SIGN_AREA, temp);
    
     	open_list[list].pointer[0] = x;
     	open_list[list].pointer[1] = y + buffer_length;
     }
     else
     {
     	read_block(index + FILE_SIGN_AREA, temp);
     	if (temp[2] + (buffer_length - z) / B + 1 > FILE_BLOCK_LENGTH)
     	{
     		printf("文件分配数组不够分配\n");
     		return ERROR;
     	}
    
    
     	read_block(x, temp);
     	strncat_s(temp + y,sizeof(temp + y + z), open_list[list].buffer, z);		write_block(x, temp);
    
    
     	//******************寻找文件区(目录项之后)的空闲块,分配新块
     	for (i = 0; i < (buffer_length - z) / B; i++)
     	{
     		for (j = K + FILE_NUM; j < L; j++)
     		{
     			read_block((j - K) / B, temp);
     			if (temp[(j - K) % B] == FREE)
     			{
     				freed = j;
    
     				break;
     			}
     		}
     		if (j == L)
     		{
     			printf("磁盘已满,分配失败\n");
     			return ERROR;
     		}
    
     		Init_block(temp, B);
     		strncpy_s(temp, (open_list[list].buffer + z + (i*B)), B);
     		write_block(freed, temp);
    
     		read_block((freed - K) / B, temp);
     		temp[(freed - K) % B] = BUSY;
     		write_block((freed - K) / B, temp);
    
     		read_block(index + FILE_SIGN_AREA, temp);
     		temp[2] ++;
     		temp[2 + temp[2]] = freed;
     		write_block(index + FILE_SIGN_AREA, temp);
     	}
    
     	for (j = K + FILE_NUM; j < L; j++)
     	{
     		read_block((j - K) / B, temp);
     		if (temp[(j - K) % B] == FREE)
     		{
     			freed = j;
     			break;
     		}
     	}
     	if (j == L)
     	{
     		printf("磁盘已满,分配失败\n");
     		return ERROR;
     	}
     	Init_block(temp, B);
    
     	strncpy_s(temp, (open_list[list].buffer + z + (i*B)), (buffer_length - z) % B);
     	write_block(freed, temp);
     	read_block((freed - K) / B, temp);
     	temp[(freed - K) % B] = BUSY;
     	write_block((freed - K) / B, temp);
     	read_block(index + FILE_SIGN_AREA, temp);
     	temp[2] ++;
     	temp[2 + temp[2]] = freed;
     	write_block(index + FILE_SIGN_AREA, temp);
    
    
     	read_block(index + FILE_SIGN_AREA, temp);
     	temp[1] += buffer_length;
     	write_block(index + FILE_SIGN_AREA, temp);
    
     	open_list[list].pointer[0] = freed;
     	open_list[list].pointer[1] = (buffer_length - z) % B;
     }
    
    }
    int lseek(int index, int pos)
    {
     int i;
     int list = -1;
     char temp[B];
     int pos_i = pos / B;
     int pos_j = pos % B;
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].filesignnum == index)
     	{
     		list = i;
     		break;
     	}
     }
    
     if (list == -1)
     {
     	printf("没找到当前索引号文件,操作失败...\n");
     	return ERROR;
     }
     if (open_list[list].flag != BUSY) {
     	printf("输入的索引号有误,操作失败...\n");
     	return ERROR;
     }
     read_block(open_list[list].filesignnum + FILE_SIGN_AREA, temp);
     if (pos_i > temp[2] - 1)
     {
     	printf("异常越界,定位失败\n");
     	return ERROR;
     }
    
    
     open_list[list].pointer[0] = temp[3 + pos_i];
     open_list[list].pointer[1] = pos_j;
     printf("指针修改成功...\n");
    
     return OK;
    
    
    }
    
    
    void Init()
    /**************************初始化磁盘
    将磁盘全部置空
    然后创建0号文件描述符为根目录的文件描述符
    初始化位图区
    ***************************/
    {
    
     int i;
     char temp[B];
    
    
     for (i = 0; i < L; i++)
     {
     	Init_block(temp, B);
     	write_block(i, temp);
     }
    
     for (i = K; i < L; i++)
     {
     	read_block((i - K) / B, temp);
     	temp[(i - K) % B] = FREE;
     	write_block((i - K) % B, temp);
     }
    
    
     filesign temp_cnt_sign;
     temp_cnt_sign.filesign_flag = 1;
     temp_cnt_sign.file_length = 0;
     temp_cnt_sign.file_block = FILE_BLOCK_LENGTH;
     Init_block(temp, B);
     temp[0] = temp_cnt_sign.filesign_flag;
     temp[1] = temp_cnt_sign.file_length;
     temp[2] = temp_cnt_sign.file_block;
    
     for (i = 0; i < FILE_BLOCK_LENGTH; i++)
     {
     	temp[i + 3] = K + i;
     }
     write_block(FILE_SIGN_AREA, temp);
     read_block(0, temp);
     for (i = 0; i < FILE_NUM; i++)
     {
     	temp[i] = FREE;
     }
     write_block(0, temp);
    }
    
    int create(char filename[])
    /**************************根据文件名创建文件。
    .找空闲文件描述符
    .在文件目录里为新创建的文件分配一个目录项,(可能需要为目录文件分配新的磁盘块)
    .在分配到的目录项里记录文件名以及描述符编号
    .返回状态信息
    ***************************/
    {
     int i;
     int frees;
     int	freed;
     int freed2;
     char temps[B];
     char tempc[B];
     char temp[B];
     for (i = K; i < K + FILE_NUM; i++)
     {
     	read_block((i - K) / B, temp);
     	if (temp[(i - K) % B] == BUSY)
     	{
     		read_block(i, temp);
     		if (strncmp(temp + 1, filename, FILE_NAME_LENGTH) == 0)
     		{
     			printf("该目录已经存在文件名为%s的文件\n", filename);
     			return ERROR;
     		}
     	}
     }
     for (i = FILE_SIGN_AREA; i < K; i++)
     {
     	read_block(i, temp);
     	if (temp[0] == FREE)
     	{
     		frees = i;
     		break;
     	}
     }
     if (i == K)
     {
     	printf("没有空闲的文件描述符\n");
     	return ERROR;
     }
    
     for (i = K; i < K + FILE_NUM; i++)
     {
     	read_block((i - K) / B, temp);
     	if (temp[(i - K) % B] == FREE)
     	{
     		freed = i;
     		break;
     	}
     }
     if (i == K + FILE_NUM)
     {
     	printf("文件个数已达上限\n");
     	return ERROR;
     }
    
     for (i = K + FILE_NUM; i < L; i++)
     {
     	read_block((i - K) / B, temp);
     	if (temp[(i - K) % B] == FREE)
     	{
     		freed2 = i;
     		break;
     	}
     }
     if (i == L)
     {
     	printf("磁盘已满,分配失败\n");
     	return ERROR;
     }
    
    
     filesign temp_filesign;
     contents temp_contents;
    
     temp_filesign.filesign_flag = 1;
     temp_filesign.file_length = 0;
     temp_filesign.file_block = 1;
    
    
     Init_block(temps, B);
     temps[0] = temp_filesign.filesign_flag;
     temps[1] = temp_filesign.file_length;
     temps[2] = temp_filesign.file_block;
     temps[3] = freed2;
     for (i = 4; i < FILE_BLOCK_LENGTH; i++)
     {
     	temps[i] = '\0';
     }
     write_block(frees, temps);
    
    
     temp_contents.filesignnum = frees - FILE_SIGN_AREA;
     strncpy_s(temp_contents.filename, filename, FILE_NAME_LENGTH);
    
     Init_block(tempc, B);
     tempc[0] = temp_contents.filesignnum;
     tempc[1] = '\0';
     strcat_s(tempc, temp_contents.filename);
     write_block(freed, tempc);
    
    
     read_block((freed - K) / B, temp);
     temp[(freed - K) % B] = BUSY;
     write_block((freed - K) / B, temp);
    
     read_block((freed2 - K) / B, temp);
     temp[(freed2 - K) % B] = BUSY;
     write_block((freed2 - K) / B, temp);
    
    
     read_block(FILE_SIGN_AREA, temp);
     temp[1]++;
     write_block(FILE_SIGN_AREA, temp);
    
     return OK;
    
    
    }
    
    int destroy(char * filename)
    /**************************删除指定文件
    .在目录里搜索该文件的描述符编号
    .删除该文件对应的目录项并更新位图
    .释放文件描述符
    .返回状态信息
    ***************************/
    {
     int i;
     int dtys;
     int dtyd;
     int use_block;
     int index;
     char temp[B];
     char tempd[B];
    
    
    
     for (i = K; i < K + FILE_NUM; i++)
     {
     	read_block((i - K) / B, temp);
     	if (temp[(i - K) % B] == BUSY)
     	{
     		read_block(i, temp);
     		if (strncmp(temp + 1, filename, FILE_NAME_LENGTH) == 0)
     		{
     			dtyd = i;
     			dtys = temp[0] + FILE_SIGN_AREA;
     			index = temp[0];
     			break;
     		}
     	}
     }
     if (i == K + FILE_NUM)
     {
     	printf("没有找到该文件\n");
     	return ERROR;
     }
    
     int list = -1;
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].filesignnum == index)
     	{
     		list = i;
     		break;
     	}
     }
     if (open_list[list].flag == BUSY && list != -1)
     {
     	printf("该文件已经被打开,需要关闭才能删除\n");
     	return ERROR;
     }
    
    
    
     read_block(dtys, temp);
     use_block = temp[2];
     for (i = 0; i < use_block; i++)
     {
     	read_block((temp[i + 3] - K) / B, tempd);
     	tempd[(temp[i + 3] - K) % B] = FREE;
     	write_block((temp[i + 3] - K) / B, tempd);
     }
    
     Init_block(temp, B);
     write_block(dtys, temp);
    
     Init_block(temp, B);
     write_block(dtyd, temp);
    
     read_block((dtyd - K) / B, temp);
     temp[(dtyd - K) % B] = FREE;
     write_block((dtyd - K) / B, temp);
     read_block(FILE_SIGN_AREA, temp);
     temp[1]--;
     write_block(FILE_SIGN_AREA, temp);
    
    
     return OK;
    
    }
    int open(char * filename)
    /***************************打开文件t
    该函数返|回的索引号可用于后续的read, write, lseek, 或close 操作
    .搜索目录找到文件对应的描述符序号
    .在打开文件表中分配一个表目
    .在分配到的表目中把读写指针置为并记录描述符编号
    .读入文件t的第一块到ì读写缓冲区中
    .返回分配到的表à目在打开文件表中的索引号
    ***************************/
    {
     int i;
     int opd;
     int ops;
     int list;
     char temp[B];
     int index;
     for (i = K; i < K + FILE_NUM; i++)
     {
     	read_block((i - K) / B, temp);
     	if (temp[(i - K) % B] == BUSY)
     	{
     		read_block(i, temp);
     		if (strncmp(temp + 1, filename, FILE_NAME_LENGTH) == 0)
     		{
     			opd = i;
     			ops = temp[0];
    
     			break;
     		}
     	}
     }
     if (i == K + FILE_NUM)
     {
     	printf("没有找到该文件\n");
     	return ERROR;
     }
    
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].filesignnum == ops && open_list[i].flag == BUSY)
     	{
     		printf("该文件已经被打开\n");
     		return ERROR;
     	}
     }
    
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].flag != BUSY)
     	{
     		list = i;
     		break;
     	}
     }
    
    
     open_list[list].filesignnum = ops;
     open_list[list].flag = BUSY;	//设置标志位为占用	
    
     index = open_list[list].filesignnum;
     lseek(index, 0);
    
     Init_block(open_list[list].buffer, BUFFER_LENGTH);
     read_block(open_list[list].pointer[0], temp);
     strncpy_s(open_list[list].buffer, temp, BUFFER_LENGTH);
     return OK;
    
    }
    
    int close(int index)
    /***************************关闭文件t
    .把缓冲区的内容写入磁盘
    .释放该文件再打开文件表中对应的表目
    .返回状态信息
    ***************************/
    {
     int i;
     int list = -1;
     char temp[B];
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].filesignnum == index)
     	{
     		list = i;
     		break;
     	}
     }
     if (list == -1)
     {
     	printf("没找到当前索引号文件t,操作失败\n");
     	return ERROR;
     }
     if (open_list[list].flag != BUSY) {
     	printf("输入的索引号有误,操作失败\n");
     	return ERROR;
     }
    
     write_buffer(index, list);
    
     Init_block(open_list[list].buffer, BUFFER_LENGTH);
     open_list[list].filesignnum = FREE;
     open_list[list].flag = FREE;
     open_list[list].pointer[0] = NULL;
     open_list[list].pointer[1] = NULL;
     return OK;
    }
    int read(int index, int mem_area, int count)
    {
     int i;
     int list = -1;
     char temp[B];
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].filesignnum == index)
     	{
     		list = i;
     		break;
     	}
     }
     if (list == -1)
     {
     	printf("没找到当前索引号文件,操作失败...\n");
     	return ERROR;
     }
     if (open_list[list].flag != BUSY) {
     	printf("输入的索引号有误,操作失败...\n");
     	return ERROR;
     }
    
     char temp_output[OUTPUT_LENGTH];
     Init_block(temp_output, OUTPUT_LENGTH);
     char output[OUTPUT_LENGTH];
     Init_block(output, OUTPUT_LENGTH);
    
     read_block(FILE_SIGN_AREA + index, temp);
     int file_length = temp[1];
     int file_block = temp[2];
     int file_area;
    
     for (i = 0; i < file_block; i++)
     {
     	read_block(FILE_SIGN_AREA + index, temp);
     	read_block(temp[3 + i], temp);
     	strncpy_s(temp_output + i*B, sizeof(B), temp, B);
     }
     read_block(FILE_SIGN_AREA + index, temp);
     read_block(temp[3 + i], temp);
     strncpy_s(temp_output + i*B, sizeof(B), temp, B);
    
     int x = open_list[list].pointer[0];
     int y = open_list[list].pointer[1];
    
     for (i = 0; i < file_block; i++)
     {
     	read_block(FILE_SIGN_AREA + index, temp);
     	if (temp[3 + i] == x)
     	{
     		break;
     	}
     }
     file_area = i * B + y;
    
     for (i = 0; i < count; i++)
     {
     	output[i + mem_area] = temp_output[i + file_area];
     }
    
     printf("%s\n", output + mem_area);
     return OK;
    }
    int write(int index, int mem_area, int count)
    {
     int i;
     int list = -1;
     int input_length;
     char temp[B];
    
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].filesignnum == index)
     	{
     		list = i;
     		break;
     	}
     }
     if (list == -1) {
     	printf("没找到当前索引号文件,操作失败...\n");
     	return ERROR;
     }
     if (open_list[list].flag != BUSY) {
     	printf("输入的索引号有误,操作失败...\n");
     	return ERROR;
     }
    
     char input[INPUT_LENGTH];
     Init_block(input, INPUT_LENGTH);
     i = 0;
     fflush(stdin);
     while (scanf_s("%c", &input[i]))
     {
     	if (input[i] == '\n')
     	{
     		input[i] == '\0';
     		break;
     	}
     	i++;
     }
     input_length = i;
     if (count <= BUFFER_LENGTH)
     {
     	strncat_s(open_list[list].buffer, BUFFER_LENGTH, input + mem_area, count);			//存入缓冲区
     }
     else
     {
     	int rest;
     	for (i = 0; i < BUFFER_LENGTH; i++)
     	{
     		if (open_list[list].buffer[i] == FREE)
     		{
     			rest = BUFFER_LENGTH - i;
     			break;
     		}
     	}
    
     	strncat_s(open_list[list].buffer + BUFFER_LENGTH - rest, BUFFER_LENGTH, input + mem_area, rest);
     	write_buffer(index, list);
     	Init_block(open_list[list].buffer, BUFFER_LENGTH);
    
    
     	for (i = 0; i < (count / BUFFER_LENGTH) - 1; i++)
     	{
     		strncpy_s(open_list[list].buffer, BUFFER_LENGTH, (input + mem_area) + rest + i*BUFFER_LENGTH, BUFFER_LENGTH);
    
     		write_buffer(index, list);
     		Init_block(open_list[list].buffer, BUFFER_LENGTH);
     	}
    
     	Init_block(open_list[list].buffer, BUFFER_LENGTH);
     	strncpy_s(open_list[list].buffer, BUFFER_LENGTH, (input + mem_area) + rest + i*BUFFER_LENGTH, count%BUFFER_LENGTH);
     	int buffer_start;
     }
     return OK;
    }
    
    void directory()
    //列表显示所有文件及其长度。
    {
     int i;
     int filenum;
     int filelength;
     char filename[FILE_NAME_LENGTH];
     char temp[B];
     char tempd[B];
     char temps[B];
     read_block(FILE_SIGN_AREA, temp);
     filenum = temp[1];						//实际存在的文件个数
     printf("\n");
     if (filenum == 0)
     {
     	printf("\t\t\t\t该目录下没有文件\n");
     }
    
     for (i = 0; i < FILE_NUM; i++)
     {
     	read_block(temp[3 + i], tempd);					//读取目录项
     	if (tempd[0] != 0)
     	{
     		read_block(tempd[0] + FILE_SIGN_AREA, temps);		//读取文件描述符
     		if (temps[0] == BUSY && tempd[0] != 0)
     		{
     			filelength = temps[1];
     			strcpy_s(filename, BUFFER_LENGTH, tempd + 1);
     			printf("%-10s\t\t%-2d字节\n", filename, filelength);
     		}
     	}
     }
    
     if (filenum != 0)
     {
     	printf("\t\t\t\t共%-2d个文件\n", filenum);
     }
    }
    
    int show_openlist()
    {
    
     int i, j;
     int openfile = 0;
     char temp[B];
     int index;
     printf("\n索引号\t\t大小\t\t文件名\n");
     for (i = 0; i < FILE_NUM; i++)
     {
     	if (open_list[i].flag == BUSY)
     	{
     		index = open_list[i].filesignnum;
     		printf("  %-2d", index);
     		openfile++;
     		read_block(FILE_SIGN_AREA + index, temp);
     		printf("\t\t %-2d", temp[1]);
     		//根据index(文件描述符序号)找到其目录项
     		for (j = K; j < K + FILE_NUM; j++)
     		{
     			read_block(j, temp);
     			if (temp[0] == index)
     			{
     				printf("\t\t%-10s\n", temp + 1);
     			}
     		}
     	}
     }
     return openfile;
    
    }
    void show_help()
    {
     printf("**----------------------------------------------------------------------**\n");
     printf("**    命令                   说明                                       **\n");
     printf("** dir                  显示目录内容                                    **\n");
     printf("** **\n");
     printf("** create+filename      新建以filename为文件名的文件                    **\n");
     printf("** **\n");
     printf("** delete+filename      删除以filename为文件名的文件                    **\n");
     printf("** **\n");
     printf("** open+filename        打开以filename为文件名的文件                    **\n");
     printf("** **\n");
     printf("** close                关闭index为索引的文件                           **\n");
     printf("** **\n");
     printf("** read                 请根据提示,接着要求输入索引号以及读取长度进行读**\n");
     printf("**                      取文件操作                                      **\n");
     printf("** **\n");
     printf("** write                请根据提示,接着要求输入索引号以及写入长度进行写**\n");
     printf("**                      入文件操作                                      **\n");
     printf("** **\n");
     printf("** lseek                请根据提示,接着要求输入一个不大于文件长度的数字**\n");
     printf("**                      用于定位读写指针                                **\n");
     printf("** **\n");
     printf("** help                 帮助                                            **\n");
     printf("** **\n");
     printf("** exit                 退出文件系统                                    **\n");
     printf("**----------------------------------------------------------------------**\n");
    }
    
    
    
    void show_ldisk()
    {
     int a, b;
     for (a = 0; a < K + 30; a++)
     {
     	printf("%-3d :", a);
     	for (b = 0; b< B; b++)
     	{
     		printf("%-3d ", ldisk[a][b]);
     	}
     	printf("\n");
     }
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

define.h

复制代码
    #define B		10			//存储块长度
    #define L		500			//存储块总数
    #define K		100			//保留区大小
    #define BUSY	1
    #define FREE	0
    #define OK		1
    #define ERROR	0
    #define FILE_BLOCK_LENGTH		(B-3)				//文件分配磁盘块号数组长度
    #define FILE_NAME_LENGTH		(B-1)				//最长文件名长度
    #define FILE_SIGN_AREA			((L-1-K)/B+1)		//保留区中文件标识符起始块号(位图之后)
    #define FILE_NUM				FILE_BLOCK_LENGTH	//目录内最多文件数目
    #define BUFFER_LENGTH			25					//打开文件表目中的缓冲区长度
    #define INPUT_LENGTH			100					//写文件时最大输入长度
    #define OUTPUT_LENGTH			100					//读文件时最大读出长度
    
    
    
    struct filesign {							//文件描述符
     int file_length;						//文件长度
     int filesign_flag;						//占用标识位
     int file_block;							//文件分配磁盘块号数组实际长度
     int file_block_ary[FILE_BLOCK_LENGTH];	//文件分配磁盘块号数组
    };
    
    struct contents {							//目录项
     char filename[FILE_NAME_LENGTH];		//文件名
     int	 filesignnum;						//文件描述符序号
    };
    
    struct openfilelist {						//打开文件表表目
     char buffer[BUFFER_LENGTH];				//读写缓冲区
     int pointer[2];							//读写指针(文件内容的位置)
     int filesignnum;						//文件描述符
     int flag;								//占用符
    };
    
    char ldisk[L][B];						//用字符数组模拟磁盘
    
    openfilelist open_list[FILE_NUM];		//打开文件表
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

main.cpp

复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    //#include <iostream.h>
    
    
    #include "define.h"
    #include "operation.h"
    
    #define DIR		0
    #define	CREATE	1
    #define	DELETE	2
    #define	OPEN	3
    #define	CLOSE	4
    #define	READ	5
    #define	WRITE	6
    #define HELP	7
    #define LSEEK	8
    #define EXIT	9
    #define	OPLIST	10
    #define LDISK	11
    #define CH_LENGTH	20
    
    
    int main()
    {
    
     printf("\t\t\t文件系统使用帮助如下\n");
     show_help();
     Init();
     create("test1");
     create("test2");
     create("test3");
     open("test1");
     open("test3");
    
     char ch[CH_LENGTH];
     Init_block(ch, CH_LENGTH);
     while (gets_s(ch))
     {
    
     	int cmd;
     	char filename[FILE_NAME_LENGTH];
     	//初始化
    
     	cmd = -1;
     	Init_block(filename, FILE_NAME_LENGTH);
     	if (strncmp("dir", ch, 3) == 0)			//浏览目录dir(non)
     	{
     		cmd = DIR;
     	}
     	if (strncmp("create", ch, 6) == 0)			//创建文件命令create(filename)
     	{
     		cmd = CREATE;
     		strcat_s(filename,20, ch + 7);
     	}
     	if (strncmp("delete", ch, 6) == 0)			//删除文件命令delete(filename)
     	{
     		cmd = DELETE;
     		strcat_s(filename,20, ch + 7);
     	}
     	if (strncmp("open", ch, 4) == 0)			//打开文件命令open(filename)
     	{
     		cmd = OPEN;
     		strcat_s(filename,20, ch + 5);
     	}
     	if (strncmp("close", ch, 5) == 0)			//关闭文件命令close(index)
     	{
     		cmd = CLOSE;
     	}
     	if (strncmp("read", ch, 4) == 0)			//读文件命令read(index)
     	{
     		cmd = READ;
     	}
     	if (strncmp("write", ch, 5) == 0)			//写文件命令write(index)
     	{
     		cmd = WRITE;
     	}
     	if (strncmp("lseek", ch, 5) == 0)			//指针命令lseek(index,pos)
     	{
     		cmd = LSEEK;
     	}
     	if (strncmp("oplist", ch, 6) == 0)			// 查看打开文件表
     	{
     		cmd = OPLIST;
     	}
     	if (strncmp("exit", ch, 4) == 0)			// 退出命令exit
     	{
     		cmd = EXIT;
     		break;
     	}
     	if (strncmp("ldisk", ch, 5) == 0)			//查看硬盘内容
     	{
     		cmd = LDISK;
     	}
     	if (strncmp("help", ch, 4) == 0)			//帮助命令help(non)
     	{
     		cmd = HELP;
     	}
     	int index, count, pos;
     	switch (cmd)
     	{
     	case DIR:
     		directory();
     		printf("----------------------------------------------\n");
     		break;
     	case CREATE:
     		if (create(filename) == OK)
     		{
     			printf("创建文件成功\n");
     		}
     			
     		printf("----------------------------------------------\n");
     		break;
     	case DELETE:
     		if (destroy(filename) == OK)
     			printf("删除文件成功\n");
     		printf("----------------------------------------------\n");
     		break;
     	case OPEN:
     		if (open(filename) == OK)
     			printf("打开文件成功\n");
     		printf("----------------------------------------------\n");
     		break;
     	case CLOSE:
     		if (show_openlist() == 0)
     		{
     			printf("当前没有文件被打开\n");
     			printf("----------------------------------------------\n");
     			break;
     		}
     		printf("请输入要关闭文件的索引号:\n");
     		scanf_s("%d", &index);
     		if (close(index) == OK)
     			printf("关闭操作成功\n");
     		printf("----------------------------------------------\n");
     		break;
     	case READ:
     		if (show_openlist() == 0)
     		{
     			printf("当前没有文件被打开\n");
     			printf("----------------------------------------------\n");
     			break;
     		}
     		printf("请输入要读取文件的索引号:\n");
     		scanf_s("%d", &index);
     		printf("请输入想要要读取文件长度:\n");
     		scanf_s("%d", &count);
     		if (read(index, 0, count) == OK)
     			printf("读文件操作成功\n");
     		printf("----------------------------------------------\n");
     		break;
     	case WRITE:
     		if (show_openlist() == 0)
     		{
     			printf("当前没有文件被打开\n");
     			printf("----------------------------------------------\n");
     			break;
     		}
     		printf("请输入要写入文件的索引号:\n");
     		scanf_s("%d", &index);
     		printf("请输入想要写入文件长度:\n");
     		scanf_s("%d", &count);
     		if (write(index, 0, count) == OK)
     			printf("写入操作成功\n");
     		printf("----------------------------------------------\n");
     		break;
     	case LSEEK:
     		if (show_openlist() == 0)
     		{
     			printf("当前没有文件被打开\n");
     			printf("----------------------------------------------\n");
     			break;
     		}
     		printf("请输入要写入文件的索引号:\n");
     		scanf_s("%d", &index);
     		printf("请输入想要设置的文件相对位置\n");
     		scanf_s("%d", &pos);
     		lseek(index, pos);
     		printf("----------------------------------------------\n");
     		break;
     	case OPLIST:
     		if (show_openlist() == 0)
     		{
     			printf("\t\t\n当前没有文件被打开\n");
     			printf("----------------------------------------------\n");
     			break;
     		}
     		printf("----------------------------------------------\n");
     		break;
     	case HELP:
     		show_help();
     		break;
     	case LDISK:
     		show_ldisk();
     		break;
     	default:
     		printf("指令错误\n");
     		printf("----------------------------------------------\n");
     		break;
     	}
     	fflush(stdin);
     	Init_block(ch, CH_LENGTH);
     }
     system("pause");
     return 0;
    }
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

全部评论 (0)

还没有任何评论哟~