实验四 文件系统实验报告

合集下载

文件管理的实验报告(3篇)

文件管理的实验报告(3篇)

第1篇一、实验目的1. 理解文件管理的概念和重要性。

2. 掌握文件系统的基本结构和工作原理。

3. 学会使用文件管理工具进行文件操作。

4. 了解文件系统优化和故障处理方法。

二、实验环境1. 操作系统:Windows 102. 文件管理工具:Windows资源管理器3. 实验数据:实验过程中所创建和操作的文件、文件夹三、实验内容1. 文件系统的基本概念(1)文件:文件是存储在存储设备上的数据集合,具有特定的文件名和文件属性。

(2)文件夹:文件夹是用于组织和管理文件的容器,可以包含多个文件和子文件夹。

(3)文件系统:文件系统是操作系统用于管理存储设备上的文件和文件夹的机制。

2. 文件系统的基本操作(1)创建文件:在资源管理器中,右键单击目标位置,选择“新建”->“文本文档”或“新建”->“文件夹”等操作创建文件或文件夹。

(2)重命名文件:选中文件或文件夹,右键单击,选择“重命名”进行修改。

(3)移动文件:选中文件或文件夹,右键单击,选择“剪切”或“复制”,然后在目标位置粘贴。

(4)复制文件:选中文件或文件夹,右键单击,选择“复制”,然后在目标位置粘贴。

(5)删除文件:选中文件或文件夹,右键单击,选择“删除”。

(6)恢复文件:在回收站中,右键单击已删除的文件或文件夹,选择“还原”。

3. 文件系统的目录结构(1)单级目录结构:所有文件和文件夹都存储在一个根目录下,易于管理,但存在文件名冲突、文件查找效率低等问题。

(2)多级目录结构:将文件和文件夹组织成树状结构,便于管理和查找,解决了单级目录结构的缺点。

4. 文件系统优化(1)定期清理磁盘碎片:磁盘碎片会影响文件读写速度,可以通过磁盘清理工具或系统自带的磁盘碎片整理程序进行优化。

(2)合理分配磁盘空间:根据实际需求,将磁盘空间分配给不同分区,提高磁盘利用率。

(3)限制文件权限:设置文件和文件夹的访问权限,保护数据安全。

5. 文件系统故障处理(1)磁盘损坏:使用数据恢复软件尝试恢复数据,或更换磁盘。

文件系统 实验报告

文件系统 实验报告

文件系统实验报告引言文件系统是操作系统中的一部分,用于管理计算机中的文件和目录。

它提供了数据的存储、访问、组织和管理功能,是操作系统的基础之一。

本实验通过实现一个简单的文件系统来深入理解文件系统的原理和实现方式。

实验目的1. 了解文件系统的基本概念和原理;2. 学习文件系统的设计和实现方法;3. 掌握文件系统的基本操作。

实验环境本次实验使用的是Ubuntu 20.04操作系统。

实验步骤1. 文件系统的设计在开始实现文件系统之前,我们首先需要设计文件系统的结构和功能。

1.1 文件系统的结构文件系统通常由三个主要部分组成:文件控制块、目录和数据块。

文件控制块用于存储文件的属性和元数据,目录用于组织文件和子目录,数据块用于存储文件的实际内容。

1.2 文件系统的功能文件系统需要提供以下功能:- 文件的创建、读取、修改和删除;- 目录的创建、读取、修改和删除;- 文件和目录的查找;- 文件的权限管理。

2. 文件系统的实现2.1 文件系统的初始化在实现文件系统之前,我们首先需要初始化文件系统。

包括创建超级块、位图和根目录,并将它们写入磁盘。

2.2 文件和目录的操作在文件系统中,我们需要实现文件和目录的基本操作,包括创建文件、创建目录、读取文件内容、修改文件内容和删除文件。

2.3 文件系统的其他操作除了基本的文件和目录操作之外,文件系统还需要实现其他一些功能,如文件查找、权限管理等。

3. 文件系统的测试在完成文件系统的实现后,我们需要对其进行测试,以验证其功能是否正常。

3.1 创建文件和目录我们首先创建一些文件和目录,检查它们是否被正确地写入磁盘,并且能够被正确地读取。

3.2 读取和修改文件我们随机选择一些文件,读取它们的内容,并对其内容进行修改。

修改后,我们再次读取文件,确保修改成功。

3.3 删除文件和目录我们尝试删除一些文件和目录,并检查它们是否被成功地删除。

4. 结果与讨论经过测试,我们发现我们实现的文件系统功能正常,能够按照我们的预期进行文件和目录的创建、读取、修改和删除等操作。

文件系统的构建实验报告

文件系统的构建实验报告

文件系统的构建实验报告 实验名称:文件系统的构建实验目的:掌握磁盘的工作原理和操作系统进行文件管理的原理实验原理:硬盘的MBR :MBR (Main Boot Record ),按其字面上的理解即为主引导记录区,位于整个硬盘的0磁道0柱面1扇区。

在总共512字节的主引导扇区中,MBR 只占用了其中的446个字节(偏移0000--偏移01BD ),另外的64个字节(偏移01BE--偏移01FD )交给了DPT(Disk Partition Table 硬盘分区表),最后两个字节"55,AA"(偏移01FE- 偏移01FF )是分区的结束标志。

这个整体构成了硬盘的主引导扇区。

硬盘依据分区表中的信息把硬盘划分为最多四个分区(对于扩展分区,可进一步划分为多个逻辑分区)。

U 盘采用类似的方法划分分区。

每个分区或软盘上可建立独立的文件系统。

下图是FAT 文件系统空间分布结构。

实验内容:在掌握磁盘的工作原理和操作系统进行文件管理原理的基础上,自行设计实现在磁盘上建立文件系统的软件,该软件应该具有与Format 类似的功能,至少支持一种文件系统格式,如FAT 、NTFS 或EXT2,至少能够对一种媒体进行格式化,如软盘,U 盘或硬盘(不得在实验室的机器上进行硬盘格式化的实验)等。

不能直接调用操作系统提供的格式化工具或类似SHFormatDrive ()的高层系统函数实现该软件。

在Windows 环境可使用biosdisk()函数完成底层盘操作,在Linux 环境上可参考format 的源代码。

比较自己设计实现的软件.与FORMAT ,分析存在什么异同。

背景知识介绍 一个分区或磁盘能作为文件系统使用前,需要初始化,并将记录数据结构写到磁盘上。

这个过程就叫建立文件系统。

大部分linux 文件系统种类具有类似的通用结构。

其中心概念是超级块superblock, i 节点inode, 数据块data block,目录块directory block, 和间接块indirection block 。

第4章文件系统实验

第4章文件系统实验
参数:
1.用于接收数据的地址(指针)(buffer)
2.单个元素的大小(size):单位是字节而不是位,例如读取一个int型数据就是4个字节
3.元素个数(count)
4.提供数据的文件指针(stream)
返回值:读取的元素的个数
(3)
通过strstr()函数将找出cpu MHz在buffer出现的位置,为之后的提取值做准备
1.切换用户
2.建立文件,并查看文件
3.创建软连接ຫໍສະໝຸດ 4.查看创建结果5.查看结果
6.修改test
7.查看结果
分析结果
(1)创建链接后,读取test1的时候,由于链接的原因,实际上读取到的是test的内容,所以读取test.txt和test01时显示的内容是一样的。修改test之后,test01也会跟着改变,显示了同步性。
format格式控制字符串
argument选择性设定字符串
sscanf会从buffer里读进数据,依照argument的设定将数据写回。
三、实现文件的拷贝,即把一个文件内容复制到另一个文件
1.创建文件
2.编译代码
3.运行
4.创建t1,t2
5.运行copy代码
6.查看结果
7.删除t1
8.查看t2
结果分析:
strstr()
包含文件:string.h
函数原型:extern char *strstr(char *str1, char *str2);
功能:找出str2字符串在str1字符串中第一次出现的位置(不包括str2的串结束符)。
返回值:返回该位置的指针,如找不到,返回空指针。
(4)
通过sscanf语句提取cpu的时钟频率
操作系统课程实验报告

实验四 文件系统实验

实验四  文件系统实验

实验四文件系统实验实验目的1)掌握文件系统的工作机理。

2)理解文件系统的主要数据结构。

3)学习较为复杂的LINUX下的编程实验内容1)设计并实现一个一级(单用户)文件系统程序a.提供以下操作:➢文件创建/删除接口命令create/delete➢目录创建/删除接口命令mkdir/rmdir➢显示目录内容命令lsb.创建的文件不要求格式和内容2)设计并实现一个二级文件系统程序a.提供用户登录;b.文件、目录要有权限实验结果及其解释说明基本上实现了简单文件系统的实现。

创建并读写文件如下图所示:打开文件、关闭文件、创建并显示子目录、删除子目录如下图所示:实验中的问题及解决首先应确定文件系统的数据结构:主目录、子目录及活动文件等。

主目录和子目录都应以文件的形式存放于磁盘,这样便于查找和修改。

由于对文件系统理解不够深刻,导致程序在一些原理上的迷糊不清,而时间较短,因此采取了简化的方法。

在写程序的开始也没有做详细的规划,因此在程序的结构上有些混乱。

在后期做了一些调整,但是整体还是有缺陷的。

另外程序只是很简单的实现了文件管理系统,只有一些非常简单的功能,而且功能考虑的也不尽全面、严谨,难免会出现一些Bug。

必须对写好的程序进行反复的调试和优化。

实验体会通过学习基本掌握了文件系统的存储结构,当遇到困难的时候,认真思考和查阅资料可以有很大的帮助。

经过这次实验,锻炼了自己的动手的能力和分析问题的能力。

在构造函数的时候可以开阔思维,同时加深自己对文件系统实现的理解。

在进行理论知识的学习时,我们一定要注意动手应用,这样可以让我们更好地掌握理论知识。

程序清单#include<stdio.h>#include<string.h>#include<stdlib.h>#define DIR_LENGTH 1024 /*路径最长可达100字节*/#define MAX_WRITE 1024*128 /*写入文字可达128k字节*/#define MEM_D_SIZE 1024*1024 /*1M磁盘空间*/#define DISKSIZE 1024 /*磁盘快的大小1K*/#define MSD 5 /*最大子目录数5 (类似五叉树)*/#define DISK_NUM MEM_D_SIZE/DISKSIZE /*磁盘快数目1024=1M/1K*/#define FATSIZE DISK_NUM*sizeof(struct fatitem) /*FAT表大小8K=8192B (理想应该是1.5K)*/#define MOFN 5 /*最大文件打开数5 (即除根以外最大深度为5)*/#define ROOT_DISK_NO FATSIZE/DISKSIZE+1 /*根目录起始盘快号9*/#define ROOT_DISK_SIZE sizeof(struct direct)/*根目录大小196*//*---------------FAT表项结构-----------------------*/struct fatitem /* size 8*/{int item; /*存放文件下一个磁盘的指针*/char em_disk; /*磁盘块是否空闲标志位0 空闲*/};/*-------------------目录项结构------------------------*/struct direct /* size 196*/{/*-----文件控制快信息-----*/struct FCB{char name[9]; /*文件/目录名8位*/char property; /*属性1位目录0位普通文件*/int size; /*文件/目录字节数(原注释位盘块数)*/int firstdisk; /*文件/目录起始盘块号*/int next; /*子目录起始盘块号*/int sign; /*1是根目录0不是根目录*/}directitem[MSD+2];};/*------------------文件打开表项结构--------------------------*/ struct opentable /* size 104*/{struct openttableitem /* size 20*/{char name[9]; /*文件名*/int firstdisk; /*起始盘块号*/int size; /*文件的大小*/}openitem[MOFN];int cur_size; /*当前打文件的数目*/};/*-------------------------------------------------------------------*/ struct fatitem *fat; /*FAT表*/struct direct *root; /*根目录*/struct direct *cur_dir; /*当前目录*/struct opentable u_opentable; /*文件打开表*/int fd=-1; /*文件打开表的序号*/char *bufferdir; /*记录当前路径的名称*/char *fdisk; /*虚拟磁盘起始地址*/void initfile();void format();void enter();void halt();int create(char *name);int open(char *name);int close(char *name);int write(int fd,char *buf,int len);int read(int fd,char *buf);int del(char *name);int mkdir(char *name);int rmdir(char *name);void dir();int cd(char *name);void print();void show();/*----------------------------------------------------------------------------------------------*//*------------------------------------------初始化文件系统--------------------------------------*/ void initfile(){fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请1M空间*/format();free(fdisk);}/*----------------------------------------------------------------------------------------------*//*------------------------------------------格式化----------------------------------------------*/ void format(){int i;FILE *fp;fat = (struct fatitem *)(fdisk+DISKSIZE); /*计算FAT表地址(为什么向后偏移1k)*/ /*-----初始化FAT表------------*/fat[0].item=-1; /*引导块*/fat[0].em_disk='1';for(i=1;i<ROOT_DISK_NO-1;i++) /*存放FAT表的磁盘块号*/{fat[i].item=i+1;fat[i].em_disk='1';}fat[ROOT_DISK_NO-1].item=-1;fat[ROOT_DISK_NO-1].em_disk='1';fat[ROOT_DISK_NO].item=-1; /*存放根目录的磁盘块号*/fat[ROOT_DISK_NO].em_disk='1';for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++){fat[i].item = -1;fat[i].em_disk = '0';}/*-----------------------------------------------*/root = (struct direct *)(fdisk+DISKSIZE+FATSIZE); /*根目录的地址*//*初始化目录*//*---------指向当前目录的目录项---------*/root->directitem[0].sign = 1;root->directitem[0].firstdisk = ROOT_DISK_NO;strcpy(root->directitem[0].name,".");root->directitem[0].next = root->directitem[0].firstdisk;root->directitem[0].property = '1';root->directitem[0].size = ROOT_DISK_SIZE;/*-------指向上一级目录的目录项---------*/root->directitem[1].sign = 1;root->directitem[1].firstdisk = ROOT_DISK_NO;strcpy(root->directitem[1].name,"..");root->directitem[1].next = root->directitem[0].firstdisk;root->directitem[1].property = '1';root->directitem[1].size = ROOT_DISK_SIZE;for(i=2;i<MSD+2;i++) /*-子目录初始化为空-*/{root->directitem[i].sign = 0;root->directitem[i].firstdisk = -1;strcpy(root->directitem[i].name,"");root->directitem[i].next = -1;root->directitem[i].property = '0';root->directitem[i].size = 0;}if((fp = fopen("disk.dat","wb"))==NULL){printf("Error:\n Cannot open file \n");return;}if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1) /*把虚拟磁盘空间保存到磁盘文件中*/ {printf("Error:\n File write error! \n");}fclose(fp);}/*----------------------------------------------------------------------------------------------*//*--------------------------------进入文件系统--------------------------------------------------*/void enter(){FILE *fp;int i;fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请1M空间*/if((fp=fopen("disk.dat","rb"))==NULL){printf("Error:\nCannot open file\n");return;}if(!fread(fdisk,MEM_D_SIZE,1,fp)) /*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/ {printf("Error:\nCannot read file\n");exit(0);}fat = (struct fatitem *)(fdisk+DISKSIZE); /*找到FAT表地址*/root = (struct direct *)(fdisk+DISKSIZE+FATSIZE);/*找到根目录地址*/fclose(fp);/*--------------初始化用户打开表------------------*/for(i=0;i<MOFN;i++){strcpy(u_opentable.openitem[i].name,"");u_opentable.openitem[i].firstdisk = -1;u_opentable.openitem[i].size = 0;}u_opentable.cur_size = 0;cur_dir = root; /*当前目录为根目录*/bufferdir = (char *)malloc(DIR_LENGTH*sizeof(char));strcpy(bufferdir,"Root:"); /*显示根目录为E:*/}/*----------------------------------------------------------------------------------------------*//*------------------------------------退出文件系统----------------------------------------------*/void halt(){FILE *fp;int i;if((fp=fopen("disk.dat","wb"))==NULL)printf("Error:\nCannot open file\n");return;}if(!fwrite(fdisk,MEM_D_SIZE,1,fp)) /*把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */{printf("Error:\nFile write error!\n");}fclose(fp);free(fdisk);free(bufferdir);for(i=0;i<MOFN;i++) /*撤销用户打开表(好像没有必要,系统自动会回收)*/{strcpy(u_opentable.openitem[i].name,"");u_opentable.openitem[i].firstdisk = 0;u_opentable.openitem[i].size = 0;}u_opentable.cur_size = 0; /*用户打开文件数清零*/return;}/*----------------------------------------------------------------------------------------------*//*----------------------------------------创建文件----------------------------------------------*/int create(char *name){int i,j;if(strlen(name)>8) /*文件名大于8位*/return(-1);for(i=2;i<MSD+2;i++) /*找到第一个空闲子目录*/{if(cur_dir->directitem[i].firstdisk==-1)break;}for(j=2;j<MSD+2;j++) /*检查创建文件是否与已存在的文件重名*/if(!strcmp(cur_dir->directitem[j].name,name))break;}if(i>=MSD+2) /*无空目录项*/return(-2);if(u_opentable.cur_size>=MOFN) /*打开文件太多(第五层)*/return(-3);if(j<MSD+2) /*文件已经存在*/return(-4);for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*找到空闲盘块j 后退出*/ {if(fat[j].em_disk=='0')break;}if(j>=DISK_NUM)return(-5);fat[j].em_disk = '1'; /*将空闲块置为已经分配*//*-----------填写目录项-----------------*/strcpy(cur_dir->directitem[i].name,name);cur_dir->directitem[i].firstdisk = j;cur_dir->directitem[i].size = 0;cur_dir->directitem[i].next = j;cur_dir->directitem[i].property = '0';/*cur_dir->directitem[i].sign 丢失*//*---------------------------------*/fd = open(name); /*打开所创建的文件*/return 0;}/*----------------------------------------------------------------------------------------------*//*----------------------------------------打开文件----------------------------------------------*/ int open(char *name){int i, j;for(i=2;i<MSD+2;i++) /*文件是否存在*/{if(!strcmp(cur_dir->directitem[i].name,name))break;if(i>=MSD+2) /*文件不存在*/return(-1);/*--------是文件还是目录-----------------------*/if(cur_dir->directitem[i].property=='1')/*是目录,不可打开读写*/return(-4);/*--------文件是否打开-----------------------*/for(j=0;j<MOFN;j++){if(!strcmp(u_opentable.openitem[j].name,name))break;}if(j<MOFN) /*文件已经打开*/return(-2);if(u_opentable.cur_size>=MOFN) /*文件打开太多*/return(-3);/*--------查找一个空闲用户打开表项-----------------------*/for(j=0;j<MOFN;j++){if(u_opentable.openitem[j].firstdisk==-1)break;}/*--------------填写表项的相关信息------------------------*/u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk;strcpy(u_opentable.openitem[j].name,name);u_opentable.openitem[j].size = cur_dir->directitem[i].size;u_opentable.cur_size++;/*----------返回用户打开表表项的序号--------------------------*/return(j);}/*----------------------------------------------------------------------------------------------*//*----------------------------------------关闭文件----------------------------------------------*/ int close(char *name){int i;for(i=0;i<MOFN;i++){if(!strcmp(u_opentable.openitem[i].name,name))break;}if(i>=MOFN) /*--文件没有打开-*/return(-1);/*-----------清空该文件的用户打开表项的内容---------------------*/strcpy(u_opentable.openitem[i].name,"");u_opentable.openitem[i].firstdisk = -1;u_opentable.openitem[i].size = 0;u_opentable.cur_size--;fd = -1; /*文件打开表的序号为-1 */return 0;}/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------写文件------------------------------------------------*/ int write(int fd, char *buf, int len){char *first;int item, i, j, k;int ilen1, ilen2, modlen, temp;/*----------用$ 字符作为空格# 字符作为换行符-----------------------*/char Space = 32; /*SPACE的ASCII码值*/char Endter= '\n';for(i=0;i<len;i++){if(buf[i] == '$') /*用$ 字符作为空格*/buf[i] = Space;else if(buf[i] == '#')buf[i] = Endter;}/*----------读取用户打开表对应表项第一个盘块号-----------------------*/item = u_opentable.openitem[fd].firstdisk;/*-------------找到当前目录所对应表项的序号-------------------------*/for(i=2;i<MSD+2;i++){if(cur_dir->directitem[i].firstdisk==item)break;}temp = i; /*-存放当前目录项的下标-*//*------找到的item 是该文件的最后一块磁盘块-------------------*/while(fat[item].item!=-1){item =fat[item].item; /*-查找该文件的下一盘块--*/}/*-----计算除该文件的最末地址-------*/first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE;/*-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------*/if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len){strcpy(first,buf);u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len;cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;}else{for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++){/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/first[i] = buf [i];}/*-----计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储-------*/ ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);ilen2 = ilen1/DISKSIZE;modlen = ilen1%DISKSIZE;if(modlen>0)ilen2 = ilen2+1; /*--还需要多少块磁盘块-*//*调试时特别注意*/for(j=0;j<ilen2;j++){for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)/*寻找空闲磁盘块*/{if(fat[i].em_disk=='0')break;}if(i>=DISK_NUM) /*--如果磁盘块已经分配完了-*/return(-1);first = fdisk+i*DISKSIZE; /*--找到的那块空闲磁盘块的起始地址-*/if(j==ilen2-1) /*--如果是最后要分配的一块-*/{for(k=0;k<len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)-j*DISKSIZE;k++) first[k] = buf[k];}else/*-如果不是要最后分配的一块--*/{for(k=0;k<DISKSIZE;k++)first[k] =buf[k];}fat[item].item = i; /*--找到一块后将它的序号存放在上一块的指针中-*/fat[i].em_disk = '1'; /*--置找到的磁盘快的空闲标志位为已分配-*/fat[i].item = -1; /*--它的指针为-1 (即没有下一块)-*/}/*--修改文件打开表用户的长度-*/u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len;/*--修改目录项的文件长度-*/cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;}return 0;}/*----------------------------------------------------------------------------------------------*//*----------------------------------------读文件------------------------------------------------*/int read(int fd, char *buf){int len = u_opentable.openitem[fd].size;char *first;int i, j, item;int ilen1, modlen;item = u_opentable.openitem[fd].firstdisk;if(len>u_opentable.openitem[fd].size) /*--欲读出的文件长度比实际文件长度长-*/ return(-1);ilen1 = len/DISKSIZE;modlen = len%DISKSIZE;if(modlen!=0)ilen1 = ilen1+1; /*--计算文件所占磁盘的块数-*/first = fdisk+item*DISKSIZE; /*--计算文件的起始位置-*/for(i=0;i<ilen1;i++)if(i==ilen1-1) /*--如果在最后一个磁盘块-*/{for(j=0;j<len-i*DISKSIZE;j++)buf[i*DISKSIZE+j] = first[j];}else /*--不在最后一块磁盘块-*/{for(j=0;j<len-i*DISKSIZE;j++)buf[i*DISKSIZE+j] = first[j];item = fat[item].item; /*-查找下一盘块-*/first = fdisk+item*DISKSIZE;}}return 0;}/*----------------------------------------------------------------------------------------------*//*----------------------------------------删除文件----------------------------------------------*/ int del(char *name){int i,cur_item,item,temp;for(i=2;i<MSD+2;i++) /*--查找要删除文件是否在当前目录中-*/{if(!strcmp(cur_dir->directitem[i].name,name))break;}cur_item = i; /*--用来保存目录项的序号,供释放目录中-*/if(i>=MSD+2) /*--如果不在当前目录中-*/return(-1);if(cur_dir->directitem[cur_item].property!='0') /*--如果删除的(不)是目录-*/return(-3);for(i=0;i<MOFN;i++) /*--如果文件打开,则不能删除,退出-*/{if(!strcmp(u_opentable.openitem[i].name,name))return(-2);}item = cur_dir->directitem[cur_item].firstdisk;/*--该文件的起始盘块号-*/while(item!=-1) /*--释放空间,将FAT表对应项进行修改-*/temp = fat[item].item;fat[item].item = -1;fat[item].em_disk = '0';item = temp;}/*-----------------释放目录项-----------------------*/cur_dir->directitem[cur_item].sign = 0;cur_dir->directitem[cur_item].firstdisk = -1;strcpy(u_opentable.openitem[cur_item].name,"");cur_dir->directitem[cur_item].next = -1;cur_dir->directitem[cur_item].property = '0';cur_dir->directitem[cur_item].size = 0;return 0;}/*----------------------------------------------------------------------------------------------*//*---------------------------------------创建子目录---------------------------------------------*/ int mkdir(char *name){int i,j;struct direct *cur_mkdir;if(strchr(name,'\\'))/*如果目录名中有'\'字符*/return(-4);if(!strcmp(name,"."))return(-6);if(!strcmp(name,".."))return(-6);if(strlen(name)>8) /*-如果目录名长度大于8位-*/return(-1);for(i=2;i<MSD+2;i++) /*-如果有空闲目录项退出-*/{if(cur_dir->directitem[i].firstdisk==-1)break;}if(i>=MSD+2) /*-目录/文件已满-*/return(-2);for(j=2;j<MSD+2;j++) /*-判断是否有重名-*/{if(!strcmp(cur_dir->directitem[j].name,name))break;if(j<MSD+2) /*-如果有重名-*/return(-3);for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*-找到空闲磁盘块j 后退出-*/{if(fat[j].em_disk=='0')break;}if(j>=DISK_NUM)return(-5);fat[j].em_disk='1'; /*-将该空闲块设置为已分配-*//*-------------填写目录项----------*/strcpy(cur_dir->directitem[i].name,name);cur_dir->directitem[i].firstdisk=j;cur_dir->directitem[i].size=ROOT_DISK_SIZE;cur_dir->directitem[i].next=j; /*-指向子目录(其实就是其本身)的起始盘块号-*/cur_dir->directitem[i].property='1';/*-sign=1为根标志,这里可以省略-*//*-所创目录在虚拟磁盘上的地址(内存物理地址)-*/cur_mkdir=(struct direct *)(fdisk+cur_dir->directitem[i].firstdisk*DISKSIZE);/*-初始化目录-*//*-指向当前目录的目录项-*/cur_mkdir->directitem[0].sign=0;cur_mkdir->directitem[0].firstdisk=cur_dir->directitem[i].firstdisk;strcpy(cur_mkdir->directitem[0].name,".");cur_mkdir->directitem[0].next=cur_mkdir->directitem[0].firstdisk;cur_mkdir->directitem[0].property='1';cur_mkdir->directitem[0].size=ROOT_DISK_SIZE;/*-指向上一级目录的目录项-*/cur_mkdir->directitem[1].sign=cur_dir->directitem[0].sign;/*-指向上一级目录的目录项-*/ cur_mkdir->directitem[1].firstdisk=cur_dir->directitem[0].firstdisk;strcpy(cur_mkdir->directitem[1].name,"..");cur_mkdir->directitem[1].next=cur_mkdir->directitem[1].firstdisk;cur_mkdir->directitem[1].property='1';cur_mkdir->directitem[1].size=ROOT_DISK_SIZE;for(i=2;i<MSD+2;i++) /*-子目录都初始化为空-*/{cur_mkdir->directitem[i].sign=0;cur_mkdir->directitem[i].firstdisk=-1;strcpy(cur_mkdir->directitem[i].name,"");cur_mkdir->directitem[i].next=-1;cur_mkdir->directitem[i].property='0';cur_mkdir->directitem[i].size=0;}return 0;}/*----------------------------------------------------------------------------------------------*//*---------------------------------------删除子目录---------------------------------------------*/ int rmdir(char *name){int i,j,item;struct direct *temp_dir;/*-检查当前目录项中有无该目录-*/for(i=2;i<MSD+2;i++){if(!strcmp(cur_dir->directitem[i].name,name))break;}if(cur_dir->directitem[i].property!='1')/*-删除的不是目录-*/return(-3);if(i>=MSD+2) /*-没有这个文件或目录-*/return(-1);/*-判断要删除的目录有无子目录-*//*-要删除的目录起始地址-*/temp_dir=(struct direct *)(fdisk+cur_dir->directitem[i].next*DISKSIZE);for(j=2;j<MSD+2;j++){if(temp_dir->directitem[j].next!=-1)break;}if(j<MSD+2) /*-有子目录或文件-*/return(-2); /*-有关联则报错,也可以采取级联删除,像Windows-*//*------------找到起始盘块号,并将其释放----------------*/item=cur_dir->directitem[i].firstdisk;fat[item].em_disk='0';/*-修改目录项-*/cur_dir->directitem[i].sign=0;cur_dir->directitem[i].firstdisk=-1;strcpy(cur_dir->directitem[i].name,"");cur_dir->directitem[i].next=-1;cur_dir->directitem[i].property='0';cur_dir->directitem[i].size=0;return 0;}/*----------------------------------------------------------------------------------------------*//*-------------------------------显示当前目录的子目录-------------------------------------------*/ void dir(){int i;for(i=0;i<MSD+2;i++){if(cur_dir->directitem[i].firstdisk!=-1) /*-如果存在子目录-*/{ /*-其本身和父目录也算?-*/printf("%s\t",cur_dir->directitem[i].name);if(cur_dir->directitem[i].property=='0') /*-文件-*/printf("%d\t\t\n",cur_dir->directitem[i].size);else /*-目录-*/printf("\t<DIR>\t\n");}}}/*----------------------------------------------------------------------------------------------*//*---------------------------------------更改当前目录-------------------------------------------*/int cd(char *name){int i,j,item;char *str,*str1;char *temp,*point,*point1;struct direct *temp_dir;temp_dir=cur_dir; /*-先用临时目录代替当前目录-*/str=name; /*-str用来记录下次查找的起始地址-*/if(!strcmp("\\",name)) /*如果输入"\" ,回根目录*/{cur_dir = root;strcpy(bufferdir,"Root:");return 0;}j=0;for(i=0;i<(int)strlen(str);i++)/*查找有两个连续是"\",即"\\",退出*/{if(name[i]=='\\')j++;if(j>=2){return -3;}}elsej=0;}if(name[0]=='\\') /*如果最后一个是"\" ,去掉这个"\"*/{temp_dir = root;strcpy(bufferdir,"Root:");str++;}if(str[strlen(str)-1] == '\\'){str[strlen(str)-1] = '\0';}str1=strchr(str,'\\'); /*-找到'\'字符的位置-*/temp = (char *)malloc(DIR_LENGTH*sizeof(char));/*-为子目录的名字分配空间-*/ while(str1!=NULL) /*-找到-*/{for(i=0;i<str1-str;i++){temp[i]=str[i];}temp[i]='\0';for(j=2;j<MSD+2;j++) /*-查找该子目录是否在当前目录中-*/{if(!strcmp(temp_dir->directitem[j].name,temp))break;}if(j>=MSD+2) /*-不在当前目录-*/return(-1);item=temp_dir->directitem[j].firstdisk;temp_dir=(struct direct *)(fdisk+item*DISKSIZE); /*-计算当前目录物理位置-*/str=str1+1;str1=strchr(str,'\\');//free(temp);}str1=str1+strlen(str);for(i=0;i<(int)strlen(str);i++)temp[i]=str[i];temp[i]='\0';for(j=0;j<MSD+2;j++) /*-查找该子目录是否在当前目录中-*/{if(!strcmp(temp_dir->directitem[j].name,temp))break;}free(temp);/*释放申请的临时空间*/if(temp_dir->directitem[j].property!='1') /*-打开的不是目录-*/return(-2);if(j>=MSD+2) /*-不在当前目录-*/return(-1);item=temp_dir->directitem[j].firstdisk;/*-当前目录在磁盘中位置-*/temp_dir=(struct direct *)(fdisk+item*DISKSIZE);if(!strcmp("..",name)){if(cur_dir->directitem[j-1].sign!=1) /*-如果子目录不是根目录-*/ {point=strchr(bufferdir,'\\');while(point!=NULL){point1=point+1; /*-减去'\'所占的空间,记录下次查找的起始地址-*/ point=strchr(point1,'\\');}*(point1-1)='\0'; /*-将上一级目录删除-*/}else{}}else if(!strcmp(".",name)){bufferdir=bufferdir; /*-如果是当前目录则不变-*/}else{if(name[0] !='\\')bufferdir = strcat(bufferdir,"\\"); /*-修改当前目录-*/bufferdir = strcat(bufferdir,name);}cur_dir=temp_dir; /*-将当前目录确定下来-*/return 0;}/*----------------------------------------------------------------------------------------------*//*---------------------------------------显示当前路径-------------------------------------------*/ void show(){printf("%s>",bufferdir);}/*----------------------------------------------------------------------------------------------*//*--------------------------------------输出提示信息--------------------------------------------*/ void print(){printf("\t\t 退出文件系统halt\n");printf("\t\t 创建文件create 文件名\n");printf("\t\t 删除文件del 文件名\n");printf("\t\t 打开文件open 文件名\n");printf("\t\t 关闭文件close 文件名\n");printf("\t\t 写文件write\n");printf("\t\t 读文件read\n\n");printf("\t\t 创建子目录mkdir 目录名\n");printf("\t\t 删除子目录rmdir 目录名\n");printf("\t\t 显示当前目录的子目录dir\n");printf("\t\t 更改当前目录cd 目录名\n");}/*----------------------------------------------------------------------------------------------*//*------------------------------------------主函数----------------------------------------------*/{FILE *fp;char ch;char a[100];char code[11][10];char name[10];int i,flag,r_size;char *contect;contect = (char *)malloc(MAX_WRITE*sizeof(char));if((fp=fopen("disk.dat","rb"))==NULL)/*如果还没有进行格式化,则要格式化*/ {printf("You have not format,Do you want format?(y/n)");scanf("%c",&ch);if(ch=='y'){initfile();printf("Successfully format! \n");}else{//return;}}enter();print();show();/*将命令全部保存在CODE数组中*/strcpy(code[0],"halt");strcpy(code[1],"create");strcpy(code[2],"open");strcpy(code[3],"close");strcpy(code[4],"write");strcpy(code[5],"read");strcpy(code[6],"del");strcpy(code[7],"mkdir");strcpy(code[8],"rmdir");strcpy(code[9],"dir");strcpy(code[10],"cd");{scanf("%s",a);for(i=0;i<11;i++){if(!strcmp(code[i],a))break;}switch(i){case 0: //*--退出文件系统--//free(contect);halt();//return;case 1: //*--创建文件--//scanf("%s",name);flag = create(name);if(flag==-1){printf("Error: \n The length is too long !\n");}else if(flag==-2){printf("Error: \n The direct item is already full !\n");}else if(flag==-3){printf("Error: \n The number of openfile is too much !\n");}else if(flag==-4){printf("Error: \n The name is already in the direct !\n");}else if(flag==-5){printf("Error: \n The disk space is full!\n");}else{printf("Successfully create a file! \n");}show();case 2://--打开文件--//scanf("%s",name);fd = open(name);if(fd == -1){printf("Error: \n The open file not exit! \n");}else if(fd == -2){printf("Error: \n The file have already opened! \n");}else if(fd == -3){printf("Error: \n The number of open file is too much! \n");}else if(fd == -4){printf("Error: \n It is a direct,can not open for read or write! \n"); }else{printf("Successfully opened! \n");}show();break;case 3://--关闭文件--//scanf("%s",name);flag = close(name);if(flag == -1){printf("Error:\n The file is not opened ! \n");}else{printf("Successfully closed! \n");}show();break;case 4:/*--写文件--*/if(fd ==-1){printf("Error:\n The file is not opened ! \n");}else{printf("Please input the file contect:");scanf("%s",contect);flag=write(fd,contect,strlen(contect));if(flag == 0){printf("Successfully write! \n");}else{printf("Error:\n The disk size is not enough! \n");}}show();break;case 5:/*--读文件--*/if(fd ==-1){printf("Error:\n The file is not opened ! \n");}else{flag = read(fd,contect);if(flag == -1){printf("Error: \n The size is over the length of the file! \n"); }else{//printf("Successfully read! \n The contect is :");for(i=0;i<u_opentable.openitem[fd].size;i++){printf("%c",contect[i]);}printf("\t\n");}}show();break;case 6://*--删除文件--scanf("%s",name);flag = del(name);if(flag == -1){printf("Error:\n The file not exit! \n");}else if(flag == -2){printf("Error:\n The file is opened,please first close it ! \n"); }else if(flag == -3){printf("Error:\n The delete is not file ! \n");}else{printf("Successfully delete! \n");}show();break;case 7://*--创建子目录--/scanf("%s",name);flag = mkdir(name);if(flag == -1){printf("Error:\n The length of name is to long! \n");}else if(flag == -2){printf("Error:\n The direct item is already full ! \n");}else if(flag == -3){printf("Error:\n The name is already in the direct ! \n");}else if(flag == -4){printf("Error:\n \\ can not in the name of a direct ! \n");}else if(flag == -5){。

文件管理系统实验报告

文件管理系统实验报告

文件管理系统实验报告文件管理系统实验报告一、引言文件管理系统是现代社会中不可或缺的一部分。

随着信息技术的迅猛发展,文件的产生和管理变得越来越重要。

本实验旨在通过设计和实现一个简单的文件管理系统,探索文件管理的原理和方法。

二、实验目的1.了解文件管理系统的基本概念和功能;2.掌握文件的创建、读取、修改和删除等操作;3.熟悉文件的组织和存储结构;4.实践文件管理系统的设计和实现。

三、实验内容1.文件的创建和读取在文件管理系统中,文件的创建和读取是最基本的操作。

通过调用系统函数,我们可以创建一个新文件,并向其中写入数据。

而读取文件则是通过指定文件路径和文件名来获取文件的内容。

2.文件的修改和删除文件的修改和删除是文件管理系统中的常见操作。

通过系统函数,我们可以打开一个已有的文件,并对其进行修改。

而删除文件则是通过指定文件路径和文件名来删除一个文件。

3.文件的组织和存储结构文件管理系统中,文件的组织和存储结构对于文件的管理和访问有着重要的影响。

常见的文件组织结构包括顺序文件、索引文件和哈希文件等。

在本实验中,我们将选择适合的文件组织结构,并实现相应的存储和检索算法。

四、实验步骤1.设计文件管理系统的数据结构在开始实验之前,我们需要先设计文件管理系统的数据结构。

这包括文件控制块(FCB)、目录项(Directory Entry)和文件块(File Block)等。

通过合理的数据结构设计,可以提高文件管理系统的性能和效率。

2.实现文件的创建和读取功能根据文件管理系统的设计,我们可以开始实现文件的创建和读取功能。

通过调用系统函数,我们可以创建一个新的文件,并向其中写入数据。

而读取文件则是通过指定文件路径和文件名来获取文件的内容。

3.实现文件的修改和删除功能文件的修改和删除是文件管理系统中的常见操作。

通过调用系统函数,我们可以打开一个已有的文件,并对其进行修改。

而删除文件则是通过指定文件路径和文件名来删除一个文件。

实验四 磁盘和文件系统管理心得

实验四 磁盘和文件系统管理心得

实验四磁盘和文件系统管理心得
实验四磁盘和文件系统管理心得
在本次实验中,我们学习了磁盘和文件系统的管理。

通过实验,我对磁盘和文件系统的概念及其管理方式有了更深入的了解和体验。

首先,磁盘管理是操作系统最基本的功能之一。

磁盘是计算机存储信息的主要设备,因此,对磁盘的管理显得尤为重要。

在实验中,我了解了磁盘的分区和格式化两个重要操作。

分区可以将一个大磁盘划分为多个逻辑分区,方便对不同的数据进行管理。

而格式化则是将分区或整个磁盘进行数据擦除,以便重新存储数据。

此外,我还学习了磁盘空间的管理,包括磁盘空间的容量、使用情况等,这些都是磁盘管理的重要内容。

其次,文件系统管理也是操作系统的重要功能之一。

文件系统是指计算机用来管理文件的一组规则和程序。

在实验中,我学习和掌握了文件的基本操作,如文件的创建、删除、拷贝和移动等。

同时,我还学习了文件系统的组成和结构,包括目录、文件描述符和索引节点等。

这些知识对文件系统的管理非常有帮助。

总之,通过本次实验,我深入了解了磁盘和文件系统的管理方式,掌握了它们的基本操作和原理,并且实践了相关操作。

这些知识对我今
后的计算机学习和工作都将有帮助。

实验4 文件系统模拟

实验4 文件系统模拟

实验4 文件系统模拟一、实验目的:设计和实现基于FAT12的模拟磁盘卷及其I/O系统的文件存取操作基本功能函数,深入领会和理解文件系统的体系结构、工作原理和设计要领。

二、实验设计1.根据FAT12设计模拟磁盘(1.44MB软盘映像文件)的磁盘组织结构及文件或空闲盘块管理方法与描述用数据结构,并实现模拟磁盘的创建和格式化操作。

2.设计和实现模拟磁盘I/O操作暨物理盘块与缓冲区(缓冲区与物理盘块大小相同)间数据交互的两个函数。

3.构建和提供用户与文件系统之间的基本接口,包括目录和文件的创建、重命名、删除和显示操作,目录的进入操作以及文件的定位及读、写操作。

4.测试系统功能并给出有效证据。

三、源程序清单和说明#include <stdio.h>#include <string.h>#include <stdlib.h>#define BlockSize 512#define DirSize 32#define RootSize 2struct ReserveBlock{int sysblocknum;/*文件系统总扇区数*/int resblocknum;/*保留扇区扇区数*/int fatblocknum;/*FA T表扇区数*/int rootblocknum;/*根目录区扇区数*/char fillchar[BlockSize-4*sizeof(int)];/*填充字节*/};struct DirBlock{char filename[11]; /*文件名限长11个字符*/charfillchar[DirSize-4*sizeof(int)-sizeof(long int)-11];/*填充字节*/long filelen; /*文件长度*/int year,month,day; /*日期*/int firstblockaddr; /*文件首块扇区号*/};struct FCBBlock{int fileid; /*文件标识*/struct DirBlock fileinfo; /*目录信息*/long filepos; /*文件读写指针*/int fdtblockaddr; /*目录项所在块号*/int fdtblockindex; /*目录项所在块内序号*/struct FCBBlock *next;/*指向下一个文件控制块的指针*/};struct ReserveBlock sys1;struct FCBBlock *fcb;struct DirBlock fil[32],*dir;/*目录项*/ int *fat1;char *str,*ptr;char fillchar[BlockSize];FILE *fp;FILE *OPENSYS(char *filename){int i;fp=fopen(filename,"rb+");fread(&sys1,1,BlockSize,fp);fat1=(int *)malloc(sys1.sysblocknum);for(i=0;i<sys1.fatblocknum;i++)fread(fat1,sizeof(int)*sys1.sysblocknum,1,fp); /*把基本的文件系统都读进来*/fseek(fp,(sys1.fatblocknum+sys1.resblocknum )*BlockSize,0);/*修改文件指针的位置*/ dir=fil;/*目录指针*/fread(dir,DirSize*32,1,fp);return fp;}int CLOSESYS(FILE *stream){int i;fseek(stream,sys1.resblocknum*BlockSize,0);fwrite(fat1,sizeof(int)*sys1.sysblocknum,1,str eam);fseek(fp,(sys1.fatblocknum+sys1.resblocknum )*BlockSize,0);fwrite(dir,DirSize*32,1,fp);fclose(fp);return 1;}int FCREA TE(char *filename)/*建立文件*/ {int i,flag=0,j,k=0,flag1=0,flag2=0,a;int n,m;while(1){a=strlen(filename);/*文件名长度*/if(a>10){printf("文件名过长\n");printf("请重新输入:");scanf("%s",filename);}elsebreak;}while(1){for(i=0;i<32;i++)if(strcmp(filename,fil[i].filename)==0){printf("该文件名已存在\n");printf("请重新输入:");flag1=1;break;}if(flag1==0)break;scanf("%s",filename);flag1=0;}for(i=(sys1.fatblocknum+sys1.resblocknum+s ys1.rootblocknum);i<sys1.sysblocknum;i++) if(fat1[i]==0)flag++;/*统计磁盘上为空数目*/if(flag==0){ printf("磁盘已满");/*统计结果为0,则磁盘已满*/return 0;}printf("空闲块数:%d\n",flag);printf("请输入文件长度:");for(j=0;j<32;j++)if(fil[j].firstblockaddr==0)break;while(1){scanf("%d",&dir[j].filelen);/*输入目录项中文件的长度*/n=(dir[j].filelen/BlockSize)+(dir[j].filelen%Bl ockSize?1:0);if(n<0||n>flag)/*文件长度小于0或大于空闲的空间*/{printf("文件长度过长\n");printf("请重新输入:");}elsebreak;}for(i=(sys1.fatblocknum+sys1.resblocknum+s ys1.rootblocknum);i<sys1.sysblocknum;i++)/ *文件内容区域*/{ if(fat1[i]==0){k++;if(flag2==0){ dir[j].firstblockaddr=i+1;flag2=1;}else{ if(k>=n)/*n 文件长度*/{ fat1[m]=i+1;fat1[i]=-1;break;}elsefat1[m]=i+1;}m=i;}}strcpy(dir[j].filename,filename);dir[j].filename[a]='\0';printf("请输入年份:");scanf("%d",&dir[j].year);printf("请输入月份:");scanf("%d",&dir[j].month);printf("请输入日期:");scanf("%d",&dir[j].day);return (1);}void LISTDIR(void)/*显示目录*/{int i,flag=0;for(i=0;i<32;i++){if(fil[i].firstblockaddr!=0){if(flag==0)printf("filename \n");flag=1; /*标示*/printf("%s\n",fil[i].filename);}}}int FDELETE(char *filename)/*删除文件*/ {int i,j,k,n,flag=0;struct FCBBlock *p;/*文件控制块指针*/p=fcb;while(p){if(strcmp(filename,fil[p->fdtblockindex].filen ame)==0)/*目录项所在内序号*/{printf("文件已经打开,请先关闭文件\n");return 0;}elsep=p->next;}for(i=0;i<32;i++)/*查找要关闭的文件*/if(strcmp(filename,fil[i].filename)==0){ flag=1;break;}if(flag==0){printf("文件不存在\n");return 0;}j=fil[i].firstblockaddr;while(1){k=fat1[j-1];fseek(fp,(j-1)*BlockSize,0);/*将指针指向文件的第一个扇区的位置*/fwrite(&fillchar,1,BlockSize,fp);fat1[j-1]=0;if(k==-1)break;elsej=k;}memset(&fil[i],0,DirSize);return 1;}int FOPEN(char *filename)/*打开文件*/ {int i,j=0,k,flag=0;struct FCBBlock *p,*q,*r;p=fcb;for(i=0;i<32;i++)if(strcmp(filename,fil[i].filename)==0)/*找到要打开的文件*/{ flag=1;break;}if(flag==0){printf("文件不存在\n");return 0;}while(p){j++;if(strcmp(filename,fil[p->fdtblockindex].filen ame)==0){printf("文件已打开\n");return 0;}q=p;p=p->next;}if(fcb==NULL){ fcb=(struct FCBBlock *)malloc(sizeof(struct FCBBlock));fcb->fileid=j+1;/*文件标示*/fcb->filepos=0;/*文件读写指针*/fcb->next=NULL;/*指向下一个文件控制指针*/fcb->fdtblockindex=i;}else{ r=(struct FCBBlock *)malloc(sizeof(struct FCBBlock));r->fileid=j+1;r->filepos=0;r->next=NULL;r->fdtblockindex=i;q->next=r;}/*f->next=NULL; */return 1;}long FGETLEN(int fileid)/*获取文件指针*/ { struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)/*寻找要找的指针*/return(p->filepos);p=p->next;}printf("error\n");return(0);}int FCLOSE(char *filename)/*关闭文件*/ { int flag=0;struct FCBBlock *f,*p;f=fcb;if(strcmp(filename,fil[fcb->fdtblockindex].file name)==0){ flag=1;fcb=fcb->next;p=fcb;while(p){p->fileid-=1;p=p->next;}return flag;}p=f;f=f->next;while(f){if(strcmp(filename,fil[f->fdtblockindex].filena me)==0){ flag=1;p=f->next;/*p=p->next;*/while(p){ p=p->next;p->fileid-=1;}free(f);return flag;}p=f;f=f->next;}if(flag==0){ printf("文件未打开\n'");return flag;}return 0;}int FREAD(char *str, int n, int fileid)/*文件块读*/{ int m,i,j=0,k,l,len;char a[3];struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)break;elsep=p->next;}len=fil[p->fdtblockindex].filelen;/*文件长度*/l=p->filepos;/*文件读写指针:该块在文件的相对位置*/printf("现在打开文件:");printf("%d\n",l);printf("是否读入这个文件?(Y/N):");scanf("%s",a);if(a[0]=='n'||a[0]=='N'){printf("输入内容:");while(1){scanf("%d",&l);if(fil[p->fdtblockindex].filelen<(l+n))/*?*/printf("too large!\ninput again:");elsebreak;}}while(1){if(n>fil[p->fdtblockindex].filelen){printf("too large!\n");printf("input read size,again:");scanf("%d",&n);}elsebreak;}str=(char*)malloc(fil[p->fdtblockindex].filelen+1);m=(len/BlockSize)+(len%BlockSize?1:0);k=fil[p->fdtblockindex].firstblockaddr;if(m>1){ fseek(fp,(k-1)*BlockSize,0);fread(str,BlockSize,1,fp);k=fat1[k-1];for(i=1;i<(m-1);i++){fseek(fp,fat1[k-1]*BlockSize,0);fread(&str[i*BlockSize],BlockSize,1,fp);k=fat1[k-1];}fseek(fp,(k-1)*BlockSize,0);fread(&str[i*BlockSize],len-i*BlockSize,1,fp);}else{ fseek(fp,(k-1)*BlockSize,0);fread(str,len,1,fp);}str[n+l]='\0';if(l!=0)str=&str[l];p->filepos=n+l;printf("%s\n",str);return 1;}void FWRITE(char *ptr, int n, int fileid){ char a[3];long l;int m,i=0,j,k=0,num,flag=0,flag1=0,b;struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)break;elsep=p->next;}l=p->filepos;printf("现在打开文件:");printf("%d\n",l);printf("是否写入这个文件?(Y/N):");scanf("%s",a);if(a[0]=='n'||a[0]=='N'){printf("输入内容:");while(1){scanf("%d",&l);if(fil[p->fdtblockindex].filelen<(l+n))printf("too large!\ninput again:");elsebreak;}}j=(l/BlockSize)+(l%BlockSize?1:0);if(l==0)j=1;num=fil[p->fdtblockindex].firstblockaddr;for(i=1;i<j;i++)num=fat1[num];do{if(flag==0){fseek(fp,(num-1)*BlockSize+l-(i-1)*BlockSi ze,0);flag=1;}else{fseek(fp,(num-1)*BlockSize,0);num=fat1[num-1];}if(((n+l)-(i-1)*BlockSize)>BlockSize ){if(flag1==0){fwrite(&ptr[0],j*BlockSize-l,1,fp);flag1=1;}else{fwrite(&ptr[j*BlockSize-l+k*BlockSize],Blo ckSize,1,fp);}}else{ m=j*BlockSize-l+(k-1)*BlockSize;b=n-(j*BlockSize-l+(k-1)*BlockSize);fwrite(&ptr[m],b,1,fp);}k++;i++;}while(((n+l)-(i-1)*BlockSize)>1);p->filepos=l+n;}int FEOF(int fileid){int flag;struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)break;}if(p->filepos>fil[p->fdtblockindex].filelen)return 0;elsereturn 1;}long FGETPOS(int fileid){struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)return (p->filepos);elsep=p->next;}printf("error!\n");return(0);}int FSETPOS(int fileid, long offset){struct FCBBlock *p;p=fcb;while(p){ if(p->fileid==fileid){ while(offset>fil[p->fdtblockindex].filelen||of fset<0){printf("set error!zhe pos >file length\n");printf("input file pos ,again:");scanf("%d",offset);}p->filepos=offset;return 1;}elsep=p->next;}printf("error!\n");return(0);}void DISPLAY(){printf("请输入命令:\n");printf("建立文件:creat\n");printf("显示目录:list\n");printf("删除文件:del\n");printf("打开文件:open\n");printf("关闭文件:close\n");printf("文件块读:read\n");printf("文件块写:write\n");printf("退出:exit\n");}void test(char *filename){char *t,cmd[10],fname[12];struct FCBBlock *p;int i,j,n,flag,len,id,flag1=0;fp=OPENSYS(filename);while(1){DISPLAY();scanf("%s",cmd);if(!strcmp(cmd,"creat")){printf("请输入文件名:\n");scanf("%s",fname);flag=FCREA TE(fname);if(flag==1)printf("文件%s 创建成功\n",fname);}else if(!strcmp(cmd,"list"))LISTDIR();else if(!strcmp(cmd,"del")){scanf("%s",fname);flag=FDELETE(fname);if(flag==1)printf("文件%s 删除成功\n",fname);}else if(!strcmp(cmd,"open")){scanf("%s",fname);flag=FOPEN(fname);if(flag==1)printf("文件%s 打开\n",fname);}else if(!strcmp(cmd,"close")){scanf("%s",fname);flag=FCLOSE(fname);if(flag==1)printf("文件%s 关闭\n",fname);}else if(!strcmp(cmd,"read")){scanf("%s",fname);p=fcb;flag1=0;while(p){ if(!strcmp(fil[p->fdtblockindex].filename,fn ame)){printf("请输入文件大小:");scanf("%d",&len);id=p->fileid;flag=FREAD(str,len,id);flag1=1;}p=p->next;}if(flag1==0)printf("文件%s 未打开,请先打开文件\n",fname);}else if(!strcmp(cmd,"write")){scanf("%s",fname);p=fcb;flag1=0;while(p){ if(!strcmp(fil[p->fdtblockindex].filename,fn ame)){printf("请输入文件大小:");do{scanf("%d",&len);if(len>fil[p->fdtblockindex].filelen)printf("文件长度过大,请重新输入:");}while(len>fil[p->fdtblockindex].fil elen);id=p->fileid;ptr=(char *)malloc(len);scanf("%s",ptr);FWRITE(ptr,len,id);flag1=1;}p=p->next;}if(flag1==0)printf("文件%s 未打开,请先打开文件\n",fname);}else if(!strcmp(cmd,"exit")){flag=CLOSESYS(fp);break;}elseprintf("error!\n");}}int main(void){ struct ReserveBlock sys;char filename[]="fatsys.dat";int *fat;int i,j;fcb=NULL;memset(&sys,255,BlockSize);printf("请输入索要创建的文件系统的大小(5~32767):");scanf("%d",&(sys.sysblocknum));sys.resblocknum=1;sys.fatblocknum=sys.sysblocknum/(BlockSize /sizeof(int))+((sys.sysblocknum%(BlockSize/sizeof(int)))?1 :0);fat=(int*)malloc(BlockSize*sys.fatblocknum);memset(fat,255,BlockSize*sys.fatblocknum);memset(fat,0,sizeof(int)*sys.sysblocknum);sys.rootblocknum=RootSize;j=sys.resblocknum+sys.fatblocknum+sys.root blocknum;for (i=0;i<j;i++)fat[i]=-1;memset(&fillchar,0,BlockSize);fp=fopen(filename,"w+b");fwrite(&sys,1,BlockSize,fp);for (i=0;i<sys.fatblocknum;i++)fwrite(fat+i*BlockSize/sizeof(int),1,BlockSize ,fp);j=sys.resblocknum+sys.fatblocknum;for(i=0;i<(sys.sysblocknum-j);i++)fwrite(&fillchar,1,BlockSize,fp);fclose(fp);free(fat);test(filename);return 0;}四、算法及关键数据结构设计1.模拟磁盘的格式化操作2.磁盘I/O操作模拟函数readBlock(int i, char *p);该函数把i#逻辑块的内容读入到指针p指向的盘块缓冲(注意读入计数处理)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四 文件系统实验 一 . 目的要求 1、用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。 2、要求设计一个 n个用户的文件系统,每次用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有Create、delete、open、close、read、write等命令。 二 . 例题:

1、设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。 2、程序采用二级文件目录(即设置主目录[MFD])和用户文件目录(UED)。另外,为打开文件设置了运行文件目录(AFD)。 3、为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。 4、算法与框图: ①因系统小,文件目录的检索使用了简单的线性搜索。 ②文件保护简单使用了三位保护码:允许读写执行、对应位为 1,对应位为0,则表示不允许读写、执行。 ③程序中使用的主要设计结构如下: 主文件目录和用户文件目录( MFD、UFD) 打开文件目录( AFD)(即运行文件目录)

M D F U F D A F D 用户名 文件名 打开文件名 文件目录指针 保护码 打开保护码 用户名 文件长度 读写指针 文件目录指针 文件名 · · 文件系统算法的流程图如下: 三 . 实验题:

1、增加 2~3个文件操作命令,并加以实现。(如移动读写指针,改变文件属性,更换文件名,改变文件保护级别)。 #include #include #include #include

#define MAXSIZE 100 #define ADDSIZE 50 #define PT elem+l-> length #define N 4 typedef struct term{/*班级和学期的结构体*/ char class1[10]; char term1[10]; }term;

typedef struct student{/*学生成绩信息的结构体*/ term st;/*班级和学期结构体放于此结构体中*/ char num[10]; char name[12]; float course[4]; float total; float average; int bit; }lnode,*stu;

typedef struct{ lnode *elem;/*指向上个结构体的指针*/ int size;/*最大能放lnode结构体成员的个数*/ int length;/*当前长度*/ }sqack,*sq; sqack *l;

void init(void)/*动态分配存储空间*/ { l-> elem=(stu)malloc(MAXSIZE*sizeof(lnode)); l-> length =0; l-> size=MAXSIZE; }

void input(void)/*输入学生的信息*/ { lnode *newbase,*p; char cla[10],ter[10],ch; int n,i;

if(l-> length> =l-> size){ newbase=(stu)realloc(l-> elem,(l-> size +ADDSIZE)*sizeof(lnode));/*追加存储空间*/ l-> elem =newbase; l-> size +=ADDSIZE; }

p=l-> elem; do { printf( "输入班级和学期(学期用这种格式,如2005年上学期 2005 1,2005年下学期 2005 2;先输入班级,回车后再输入学期)\n "); gets(cla); gets(ter); printf( "要输入多少个名单? "); scanf( "%d ",&n); printf( "输入学生的成绩\n学号\t姓名\t科目1\t科目2\t科目3\t科目4\n ");

for(i=0;i { scanf( "%s%s%d%d%d%d ",p-> num ,p-> name,p-> course[0],p-> course[1],p-> course[2],p-> course[3]); strcpy(p-> st.class1,cla); strcpy(p-> st.term1,ter); ++l-> length ; } printf( "要继续吗?(y/n) "); ch=getchar();}while(ch== 'Y '||ch== 'y '); }

void change()/*修改学生的信息*/ { lnode *p; lnode e; int flag=1,i;

char s1[10],num1[10]; printf( "输入学期和学号(输入学期以后按回车再输入学号):\n "); gets(s1); gets(num1); p=l-> elem ;

while(p <=(l-> elem+l-> length ) && flag==1)/*查找要修改的学生的信息*/ { if(strcmp(p-> num,num1)==0&&strcmp(p-> st.term1,s1)==0) flag=0;/*找到了*/ p++; }

p--; if(flag==1) printf( "找不到此学号!\n ");

printf( "%s %s ",p-> num,p-> name); for(i=0;i printf( "%d ",p-> course[i]);

printf( "\n "); printf( "输入修改信息\n ");

scanf( "%s%s%s%s ",e.st.class1,e.st.term1,&e.num,e.name); for(i=0;i scanf( "%d ",&e.course[i]); *p=e; }

void same(char *t1,char *t2,lnode *t,int *k) /*把学期和班级相同的学生信息放在结构体数组tt中*/ { int i=0; lnode *p,*q; q=t; p=l-> elem ;

while(p <=l-> elem+l-> length ) { if(strcmp(p-> st.term1,t1)==0&&strcmp(p-> st.class1 ,t2)==0) { *q=*p;q++; i++; } p++; } *k=i; }

void sort(lnode *p,int *k)/*按学生成绩从高到低排序函数*/ { int i; lnode *q,temp;

for(q=p;q { q-> total =0;

for(i=0;i q-> total =q-> total +q-> course [i];

q-> average =q-> total /N; }

for(i=0;i <*k-1;i++) for(q=p;q

if(q-> total <(q+1)-> total) { temp=*q;*q=*(q+1);*(q+1)=temp; } }

void print(lnode *q,int *k)/*输出学生的成绩*/ {

lnode *p; p=q;

for(p=q;p { printf( "%s %s ",p-> num,p-> name);

for(int i=0;i printf( "%d ",p-> course[i]);

printf( "%d %f ",p-> total,p-> average); printf( "\n "); } }

void stat()/*统计学生的成绩*/ { lnode tt[50]; char ter[10],clas[10]; int i,k;

printf( "请输入学期和班级(输入学期后按回车再输入班级):\n "); for(i=0;ter[i]!= '\n ';i++) ter[i]=getchar(); for(i=0;clas[i]!= '\n ';i++) clas[i]=getchar();

same(ter,clas,tt,&k);/*把学期和班级相同的学生信息放在结构体数组tt中*/ sort(tt,&k);/*按学生成绩从高到低排序函数*/ print(tt,&k);/*输出学生的成绩*/ }

void search1()/*按学号查*/ { lnode *p; char ter1[10]; int i,flag=1;

p=l-> elem; printf( "输入学号: "); gets(ter1);

for(p=l-> elem;p PT;p++) { if(strcmp(p-> num,ter1)==0) { flag=0; printf( "%s %s ",p-> st.term1,p-> st.class1); printf( "%s %s ",p-> num,p-> name);

for(i=0;i printf( "%d ",p-> course[i]);

printf( "%d %3.1f ",p-> total,p-> average); printf( "\n "); } }

if(flag) printf( "没有找到! "); }

void search2()/*按姓名查*/ { lnode *p; char ter1[10]; int i,flag=1; p=l-> elem;

printf( "输入姓名: ");

相关文档
最新文档