简单文件系统模拟实验

合集下载

南邮操作系统实验4.文件系统模拟实现

南邮操作系统实验4.文件系统模拟实现


关闭文件close close (fd);
实验内容及原理说明——实验4

读文件read




写文件write

nr = read (fd, buf, count); buf 为读出信息所应送入的用户数据区首地址 count 为要求传送字节数 nr 为实际读入字节数 一旦读到文件末尾,系统调用就返回,故nr可能小于 count,甚至为0 nw = write (fd, buf, count); 参数类似 read 其中 buf 是信息传送的源地址,即将buf指向的用户数 据区中的信息写入文件中

具体功能:




#include <unistd.h> #include <stdio.h> #include <fcntl.h>
实验内容及原理说明——实验4

创建文件creat(兼具打开功能)

fd = creat (filenamep, mode);


filenamep指向所要创建的文件路径名
实验4:文件系统的模拟实现

实验基本信息 实验内容说明

实验基本信息

实验名称

文件系统的模拟实现

实验类型:综合 学时:2+2 实验时间:13.5.30(下午3-4节) 地点:教5-501 实验环境:

VMWare + Ubuntu
实验内容及原理说明——实验4

实验目link、open、close、 read、write的使用,编程模拟实现文件系统基本功能 运行终端给出命令提示,请用户选择创建、删除、读、 写、退出等操作(可用数字表示不同命令) 根据用户选择命令,提示用户输入文件名、文件内容 等信息 执行用户命令

文件系统实验 模拟设计文件操作

文件系统实验 模拟设计文件操作

实验五文件系统实验一. 目的要求. 用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。

从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。

要求设计一个n个用户的文件系统,每次用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有Create、delete、open、close、read、write等命令。

二. 例题:设计一个N个用户的文件系统,每次用户可保存L个文件,一次运行用户可以打开S个文件。

程序采用二级文件目录(即设置主目录MFD)和用户文件目录(UFD)。

另外,为打开文件设置了运行文件目录,用户已打开文件表UOF.。

为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作算法与框图:因系统小,文件目录的检索使用了简单的线性搜索。

文件保护简单使用了保护码:允许读写执行、对应位为1,对应位为2,和对应位为3。

程序中使用的主要设计结构如下:主文件目录和用户文件目录(MFD、UFD)打开文件目录(UOF)(即运行文件目录)主文件目录MFD:用户文件目录UFD用户已打开文件表UOF二、实验要求:显示初始的文件目录表、输入的文件操作命令和每条命令执行后的UOF文件,程序运行后打印所有用户的文件目录表。

假定文件系统提供的文件操作有建立文件(CREATE),打开文件(OPEN),关闭文件(CLOSE),读文件(READ),写文件(WRITE)和删除文件(DELETE),在模拟程序中可以从键盘上输入文件操作命令来模拟各用户程序中所调用的各种文件操作,用一个结束命令(end)停止程序执行。

主程序结构流图如下:用输入命令来模拟用户程序中调用的文件操作,这些命令的格式和和要求如下:①建立文件:create(文件名,文件长度,文件属性)②写文件:write(文件名,记录号)有两种情况,第一种是在执行create后要求写,第二种是在执行open 后要求写,即对一个已存在的文件进行修改。

操作系统文件管理系统模拟实验

操作系统文件管理系统模拟实验

操作系统文件管理系统模拟实验在计算机科学中,操作系统是一种系统软件,负责管理计算机硬件和软件资源,并为用户和应用程序提供接口。

文件管理系统是操作系统的一个重要组成部分,它负责管理计算机系统中的文件和目录,以及提供对它们的访问和操作。

本次实验旨在模拟操作系统中文件管理系统的基本功能和操作。

我们将使用一个虚拟的文件系统,通过命令行界面来模拟用户与文件系统的交互。

以下是实验的具体内容和步骤:1. 创建虚拟文件系统首先,我们需要创建一个虚拟的文件系统。

文件系统由文件和目录组成,可以通过树状结构来表示。

我们可以使用一个数据结构来模拟文件系统的存储和管理。

2. 初始化文件系统在开始操作文件系统之前,我们需要初始化文件系统。

这包括创建根目录和设置当前目录为根目录。

3. 文件和目录的创建与删除文件和目录是文件系统的基本单位。

我们可以通过命令来创建和删除文件和目录。

例如,使用"mkdir"命令创建一个目录,使用"touch"命令创建一个空文件,使用"rm"命令删除文件或目录。

4. 文件和目录的访问权限文件和目录可以设置不同的访问权限,以保护文件系统的安全性。

我们可以使用"chmod"命令来修改文件或目录的权限。

权限通常包括读、写和执行权限。

5. 文件和目录的重命名和移动我们可以使用"mv"命令来重命名文件或目录,使用"cp"命令来复制文件或目录,使用"mv"命令来移动文件或目录。

6. 文件和目录的查找和显示我们可以使用"ls"命令来显示当前目录下的文件和目录,使用"cd"命令来切换当前目录,使用"pwd"命令来显示当前目录的路径。

此外,我们还可以使用"find"命令来查找文件或目录。

7. 文件和目录的读写操作文件可以被读取和写入。

操作系统文件管理系统模拟实验

操作系统文件管理系统模拟实验

操作系统文件管理系统模拟实验操作系统文件管理系统模拟实验一、实验目的本实验旨在通过模拟操作系统的文件管理系统,加深对操作系统文件管理的理解,锻炼操作系统的应用能力。

二、实验环境1、操作系统:Windows/Linux/MacOS2、编程语言:C/C++/Java/Python等三、实验内容1、初始化文件管理系统1.1 创建根目录,并初始化空文件目录1.2 初始化用户目录和权限设置2、文件操作2.1 创建文件2.1.1 检查文件名合法性2.1.2 检查文件是否已存在2.1.3 为新文件分配磁盘空间2.1.4 添加文件元数据信息2.2 打开文件2.2.1 检查文件是否存在2.2.2 检查用户权限2.3 读取文件内容2.3.1 读取文件权限检查2.3.2 读取文件内容2.4 写入文件内容2.4.1 写入文件权限检查2.4.2 写入文件内容2.5 删除文件2.5.1 检查文件是否存在2.5.2 检查用户权限2.5.3 释放文件占用的磁盘空间2.5.4 删除文件元数据信息3、目录操作3.1 创建子目录3.1.1 检查目录名合法性3.1.2 检查目录是否已存在3.1.3 添加目录元数据信息3.2 打开目录3.2.1 检查目录是否存在3.2.2 检查用户权限3.3 列出目录内容3.3.1 列出目录权限检查3.3.2 列出目录内容3.4 删除目录3.4.1 检查目录是否存在3.4.2 检查用户权限3.4.3 递归删除目录下所有文件和子目录3.4.4 删除目录元数据信息四、实验步骤1、根据实验环境的要求配置操作系统和编程语言环境。

2、初始化文件管理系统,创建根目录,并初始化用户目录和权限设置。

3、进行文件操作和目录操作。

五、实验结果分析根据实验步骤进行文件操作和目录操作,观察系统的运行情况并记录相关实验结果。

六、实验结论通过本实验,深入了解了操作系统中文件管理系统的相关原理和实现方式,并且通过实验操作进一步巩固了相应的应用能力。

操作系统试验模拟文件管理系统

操作系统试验模拟文件管理系统

一、实验目的和要求(必填)实验目的:通过在VC平台下编程,设计和调试一个简单的文件系统,通过模拟文件操作命令的执行,来模拟文件系统对文件及目录的管理。

实验要求:两名学生成组结对完成实验,仿真出文件系统中对文件和目录的操作。

二、实验内容(必填)文件管理:实现一个简单的文件系统三、实验原理或实验方法(必填)原理:通过结构体来描述文件和目录,利用链表知识实现目录树结构,通过对链表的操作实现整个文件系统中目录和文件的相关操作。

方法:学生两人结对进行实验,分别实现对文件和目录的操作。

对文件的操作包括:创建文件create、读文件read、写文件write、删除文件delete。

对目录的操作包括:创建目录mkdir、切换目录cd、展示目录内容dir、删除目录rm。

四、主要仪器设备或实验条件Windows操作系统,VC开发环境五、实验步骤(含实验数据记录处理)或操作设计过程记录#include "stdio.h"#include "iostream.h"#include "string.h"#define FILENAME_LENGTH 10 //文件名称长度#define COMMAND_LENGTH 10 //命令行长度#define PATH_LENGTH 30 //参数长度struct filenode{char filename[FILENAME_LENGTH];int isdir;char content[255];filenode *parent;filenode *child;filenode *prev;filenode *next;};filenode *initnode(char filename[],int isdir);void createroot();int run();int findpath(char *topath);void help();int mkdir();int create();int read();int write();int del();int rm();int cd();int dir();filenode *root,*recent,*temp,*ttemp,*temp_child;charpath[PATH_LENGTH],command[COMMAND_LENGTH],temppath[PATH_LENGTH],recen tpath[PATH_LENGTH];//创建文件或目录的存储节点filenode* initnode(char filename[],int isdir){filenode *node=new filenode;strcpy(node->filename,filename);node->isdir=isdir;node->parent=NULL;node->child=NULL;node->prev=NULL;node->next=NULL;return node;}//初始化文件系统根结点void createroot (){recent=root=initnode("/",1);root->parent=NULL;root->child=NULL;root->prev=root->next=NULL;strcpy(path,"/");}void help(){cout<<endl;cout<<"create: 建立文件。

(完整word版)操作系统文件管理系统模拟实验(word文档良心出品)

(完整word版)操作系统文件管理系统模拟实验(word文档良心出品)

文件管理系统模拟1. 实验目的通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现2. 实验内容为Linux系统设计一个简单的二级文件系统。

要求做到以下几点:(1)可以实现下列几条命令(至少4条)logi n 用户登录dir 列文件目录creat e 创建文件delete删除文件ope n 打开文件close 关闭文件read 读文件write 写文件(2) 列目录时要列出文件名、物理地址、保护码和文件长度;(3) 源文件可以进行读写保护。

3. 实验提示(1)首先应确定文件系统的数据结构:主目录、子目录及活动文件等。

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

(2)用户创建的文件,可以编号存储于磁盘上。

入file0,file1,file2 …并以编号作为物理地址,在目录中进行登记。

4. 源代码#i nclude<stdio.h>#i nclude<stri ng.h>#i nclude<stdlib.h>#defi ne MEM_D_SIZE 1024*1024 //总磁盘空间为1M#defi ne DISKSIZE 1024//磁盘块的大小1K#defi ne DISK_NUM 1024//磁盘块数目1K#defi ne FATSIZE DISK_NUM*sizeof(struct fatitem) //FAT表大小#defi ne ROOT_DISK_NO FATSIZE/DISKSIZE+1//根目录起始盘块号#defi ne ROOT_DISK_SIZE sizeof(struct direct) // 根目录大小#defi ne DIR_MAXSIZE 1024//路径最大长度为1KB#defi ne MSD 5//最大子目录数5 }ope nitem[MOFN];#defi ne MOFN 5 int cur_size; /* 当前打文件的//最大文件深度为5 数目*/#defi ne MAX_WRITE 1024*128 };//最大写入文字长度128KBstruct fatitem *fat; /*FAT 表*/ struct fatitem /* size 8*/ struct direct *root; /* 根目录*/ { struct direct *cur_dir; /* 当前int item; /* 存放文件下一个磁目录*/盘的指针*/ struct ope ntable u_ope ntable; /* char em_disk; /*磁盘块是否空闲文件打开表*/标志位0空闲*/ int fd=-1; /* 文件打开表的序}; 号*/char *bufferdir; /* 记录当前路struct direct 径的名称*/{ char *fdisk; /* 虚拟磁盘起始地/*―一文件控制快信息―一*/址*/struct FCB{ void ini tfile();char n ame[9]; /* 文件/目录void format();名8位*/ void en ter();char property; /* 属性1位void halt();目录0位普通文件*/ int create(char *n ame);int size; /* 文件/目录字int ope n( char *n ame);节数、盘块数)*/ int close(char *n ame);int firstdisk; /* 文件/目int write(i nt fd,char *buf,i nt 录起始盘块号*/ len);int next; /* 子目录起始盘int read(i nt fd,char *buf);块号*/ int del(char *n ame);int sig n; /*1 是根目录0 int mkdir(char *n ame);不是根目录*/ int rmdir(char *n ame);void dir();}directitem[MSD+2]; int cd(char *n ame);void prin t();}; void show();struct opentable void ini tfile(){struct ope {fdisk =(char{ *)malloc(MEM_D_SIZE*sizeof(char)char n ame[9]; /* 文件名*/ );/* 申请1M空间*/int firstdisk; /* 起始盘块format(); 号*/int size; /* 文件的大小*/ }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].item=-1;/*存放根目录的磁盘块号*/fat[ROOT_DISK_NO].em_disk='1'for(i=ROOT_DISK_NO+1;i<DISK_N UM;i++){fat[i].item = -1; fat[i].em_disk ='O';} _/* -------------------------------------------- */root = (struct direct*)(fdisk+DISKSIZE+FATSIZE); /* 根目录的地址*//*初始化目录*//* ------- 指向当前目录的目录项----- */root->directitem[0].sig n = 1;root->directitem[0].firstdisk=ROOT_DISK_NO;strcpy(root->directitem[0]. na me,".");root->directitem[0]. next = root->directitem[0].firstdisk;root->directitem[0].property ='1';root->directitem[0].size = ROOT_DISK_SIZE;/* ------ 指向上一级目录的目录项----- */root->directitem[1].sig n = 1;root->directitem[1].firstdisk=ROOT_DISK_NO;strcpy(root->directitem[1]. na me,"..");root->directitem[1]. next = root->directitem[0].firstdisk;root->directitem[1].property='1';root->directitem[1].size = ROOT_DISK_SIZE;if((fp = fope n("disk.dat","wb"))==NULL){prin tf("Error:\n Cannot ope n file \n");return;}for(i=2;i<MSD+2;i++) /*-子目录初始化为空-*/{root->directitem[i].sig n =0;root->directitem[i].firstdisk=-1;strcpy(root->directitem[i]. na me,"");root->directitem[i]. next =-1;root->directitem[i].property='0';root->directitem[i].size =0;}}}if((fp=fope n( "disk.dat","wb"))==NULL){prin tf("Error:\nCannotope n file \n");return;} if(fwrite(fdisk,MEM_D_SIZE,1, fp)!=1) /* 把虚拟磁盘空间保存到磁 盘文件中*/{prin tf("Error:\nFilewrite error! \n");}fclose(fp); }void en ter() {FILE *fp; int i;fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char) );/* 申请1M 空间*/if((fp=fopen( "disk.dat","rb") )==NULL){prin tf("Error:\nCa nnotope n file\n");return; }if(!fread(fdisk,MEM_D_SIZE,1, fp)) /* 把磁盘文件 disk.dat 读入 虚拟磁盘空间(内存)*/{prin tf("Error:\nCa nnotread file\n");exit(0);fat = (struct fatitem *)(fdisk+DISKSIZE); /* 找至U FAT表 地址*/root = (struct direct*)(fdisk+DISKSIZE+FATSIZE);/* 找 到根目录地址*/fclose(fp); /* ------------- 初始化用户打 开表 ----------- */ for(i=0;i<MOFN;i++) {strcpy(u_ope ntable.ope nitem[i ].name,"");u_ope ntable.ope nitem[i].first disk = -1;u_ope ntable.ope nitem[i].size =0;}u_ope ntable.cur_size = 0; cur_dir = root; /* 当前目录为根 目录*/bufferdir = (char *)malloc(DIR_MAXSIZE*sizeof(char ));strcpy(bufferdir,"Root:"); }void halt() {FILE *fp; int i;if((fp=fopen("disk.dat","wb") )==NULL){prin tf("Error:\nCa nnotope n file\n");return;if(!fwrite(fdisk,MEM_D_SIZE,1,fp)) /* 把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */{prin tf("Error:\nFile writeerror!\n");}fclose(fp);free(fdisk);free(bufferdir); return;}int create(char *n ame){int i,j;if(strle n(n ame)>8) /* 文件名大于8位*/return(-1);for(j=2;j<MSD+2;j++) /* 检查创建文件是否与已存在的文件重名*/{if(!strcmp(cur_dir->directite m[j]. name, name)) break;} if(j<MSD+2) /* 文件已经存在*/return(-4);for(i=2;i<MSD+2;i++) /* 找到第一个空闲子目录*/{if(cur_dir->directitem[i].firstdisk==-1)break;}if(i>=MSD+2) /* 无空目录项*/return(-2); if(u_ope ntable.cur_size>=MOFN) /* 打开文件太多*/return(-3);for(j=ROOT_DISK_NO+1;j<DISK_NUM; j++) /*找到空闲盘块j后退出*/{if(fat[j].em_disk=='O') 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';/* --------------------------------*/fd = ope n(n ame);return 0;}int ope n( char *n ame){int i, j;for(i=2;i<MSD+2;i++) /* 文件是否存在*/{if(!strcmp(cur_dir->directite m[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_ope ntable.ope nit em[j]. name, name)) break;}if(j<MOFN) /* 文件已经打开*/return(-2);if(u_ope ntable.cur_size>=MOFN) /* 文件打开太多*/return(-3);/* ------ 查找一个空闲用户打开表项--------------- */for(j=0;j<MOFN;j++){if(u_ope ntable.ope nitem[j].fi rstdisk==-1)break;/* ------------- 填写表项的相关信息--------------- */ u_ope ntable.ope nitem[j].firstdisk = cur_dir->directitem[i].firstdiskJ strcpy(u_ope ntable.ope nitem[j].name ,n ame);u_ope ntable.ope ni tem[j].size=cur_dir->directitem[i].size;u_ope ntable.cur_size++;/* ---------- 返回用户打开表表项的序号 ------------------------ */return(j);}int close(char *n ame){int i;for(i=0;i<MOFN;i++){if(!strcmp(u_ope ntable.ope nitem[i]. name, name))break;}if(i>=MOFN)return(-1);/* ---------- 清空该文件的用户打开表项的内容*/strcpy(u_ope ntable.ope ni tem[i].n ame,"");u_ope ntable.ope nitem[i].firstdisk = -1;u_ope ntable.ope nitem[i].size=0;u_ope ntable.cur_size--;}return 0;} int write(i nt fd, char *buf, i nt len) {char *first;int item, i, j, k;int ilen1, ilen2, modlen, temp;/* --------- 用$字符作为空格# 字符作为换行符*/char Space = 32;char En dter= '\n';for(i=0;i<le n;i++){if(buf[i] == '$')buf[i] = Space;else if(buf[i] == '#')buf[i] = En dter; }/* --------- 读取用户打开表对应表项第一个盘块号---------------------- */下标-*//* ---- 找到的item是该文件的最后一块磁盘块*/while(fat[item].item!=-1){item =fat[item].item; /*-查找该文件的下一盘块--*/}/*----- 计算出该文件的最末地址----- */first = fdisk+item*DISKSIZE+u_ope ntable. ope nitem[fd].size%DISKSIZE;/* ----- 如果最后磁盘块剩余的大小大于要写入的文件的大小*/if(DISKSIZE-u_ope ntable.ope ni tem[fd].size%DISKSIZE>le n){ strcpy(first,buf);u_ope ntable.ope ni tem[fd].sizeu_ope ntable.ope nitem[fd].size+le n;item = u_ope ntable.ope nitem[fd].firstdi sk;/* ------------ 找到当前目录所对应表项的序号------------------------- */for(i=2;i<MSD+2;i++){if(cur_dir->directitem[i].firstdisk==item)break;}temp = i; /*- 存放当前目录项的cur_dir->directitem[temp].siz ecur_dir->directitem[temp].size+l en;}else{for(i=0;i<(DISKSIZE-u_ope ntab le.ope nitem[fd].size%DISKSIZE);i ++){/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/first[i] = buf [i];/*----- 计算分配完最后一块磁盘的剩余空间(字节)还剩下多少字节未存储------------- */ile n1 = len-(DISKSIZE-u_ope ntable.ope nitem[fd].size%DISKSIZE);ile n2 = ile n1/DISKSIZE; modlen = ilen 1%DISKSIZE; if(modlen>0)ilen2 = ilen 2+1; /*--还需要多少块磁盘块-*/for(j=0;j<ile n2;j++){for(i=ROOT_DISK_NO+1;i<DISK_N UM;i++)/*寻找空闲磁盘块*/{if(fat[i].em_disk=='O')break;} if(i>=DISK_NUM) /*--如果磁盘块已经分配完了-*/return(-1);first = fdisk+i*DISKSIZE; /*-- 找到的那块空闲磁盘块的起始地址-*/if(j==ile n2-1) /*--如果是最后要分配的一块-*/{for(k=0;k<le n-(DISKSIZE-u_ope ntable.ope nitem[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_ope ntable.ope ni tem[fd].size u_ope ntable.ope nitem[fd].size+len;cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len;}return 0;}int read(i nt fd, char *buf){int len = u_ope ntable.ope nitem[fd].size;char *first;int i, j, item;int ile n1, modle n;item = u_ope ntable.ope nitem[fd].firstdi sk;ile n1 = len/DISKSIZE; modle n =len %DISKSIZE;if(modle n!=0)ilen1 = ilen 1+1; /*-- 计算文件所占磁盘的块数-*/ 项的序号,供释放目录中-*/first = fdisk+item*DISKSIZE;/*--计算文件的起始位置-*/for(i=0;i<ile n1;i++){if(i==ile n1-1) /*-- 最后一个磁盘块-*/{if(cur_dir->directitem[cur_it em].property!='0') /*-- 如果删除的(不)是目录-*/return(-3);for(j=0;j<le n-i*DISKSIZE;j++)buf[i*DISKSIZE+j]= first[j];}else /*-- 不在最后一块磁盘块-*/{for(j=0;j<le n-i*DISKSIZE;j++)buf[i*DISKSIZE+j]= first[j];item = fat[item].item;/*-查找下一盘块-*/first fdisk+item*DISKSIZE;}}return 0;} int del(char *n ame){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; /*-- 用来保存目录for(i=0;i<MOFN;i++) /*--如果文件打开,则不能删除,退出-*/{if(!strcmp(u_ope ntable.ope nit em[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].sig n = 0;cur_dir->directitem[cur_item] .firstdi sk = -1;strcpy(u_ope ntable.ope nitem[cur_item]. name,"");cur_dir->directitem[cur_item]. ne xt = -1; cur_dir->directitem[cur_item].prif(i>=MSD+2) /*--目录中-*/ return(-1);如果不在当前如果在operty = 'O';cur_dir->directitem[cur_item].size = 0;return 0;}int mkdir(char *n ame){int i,j;struct direct *cur_mkdir;if(!strcmp( name,"."))return(-4);if(!strcmp( name,".."))return(-4);if(strle n(n ame)>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_ N UM;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].n ame ,n ame);cur_dir->directitem[i].firstd isk=j;cur_dir->directitem[i].size=ROOT_DISK_SIZE;cur_dir->directitem[i]. next=jJcur_dir->directitem[i].proper ty='1';/*-所创目录在虚拟磁盘上的地址(内存物理地址)-*/cur_mkdir=(struct direct *)(fdisk+cur_dir->directitem[i].firstdisk*DISKSIZE);/*-初始化目录-*//*-指向当前目录的目录项-*/cur_mkdir->directitem[0].sig n =0;cur_mkdir->directitem[0].firstdisk=cur_dir->directitem[i].fir stdisk;strcpy(cur_mkdir->directitem[ 0]. name,".");cur_mkdir->directitem[0]. next=cur_mkdir->directitem[0].firstd isk;cur_mkdir->directitem[0].property='1';cur_mkdir->directitem[0].size=ROOT_DISK_SIZE;/*-指向上一级目录的目录项-*/cur_mkdir->directitem[1].sig n=cur_dir->directitem[O].sig n;cur_mkdir->directitem[1].firstdisk=cur_dir->directitem[O].fir stdisk;strcpy(cur_mkdir->directitem[ 1]. name,"..");cur_mkdir->directitem[1]. next =cur_mkdir->directitem[1].firstd isk;cur_mkdir->directitem[1].prop erty='1';cur_mkdir->directitem[1].size=ROOT_DISK_SIZE;for(i=2;i<MSD+2;i++) /*-子目录都初始化为空-*/{cur_mkdir->directitem[i].sig n=0;cur_mkdir->directitem[i].firs tdisk=-1;strcpy(cur_mkdir->directitem[ i]. name,"");cur_mkdir->directitem[i]. next=-1;cur_mkdir->directitem[i].prop erty='0';cur_mkdir->directitem[i].size=0;}return 0;}int rmdir(char *n ame){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(i>=MSD+2) /*- 没有这个文件或目录-*/return(-1);if(cur_dir->directitem[i].property!='1')/*- 删除的不是目录-*/return(-3);/*-判断要删除的目录有无子目录-*/temp_dir=(struct direct *)(fdisk+cur_dir->directitem[i]. next*DISKSIZE);for(j=2;j<MSD+2;j++){if(temp_dir->directitem[j]. ne xt!=-1)break;}if(j<MSD+2) /*- 有子目录或文件-*/ return(-2);/* ----------- 找到起始盘块号并将其释放 ---------- */item=cur_dir->directitem[i].f irstdisk;fat[item].em_disk='0';/*-修改目录项-*/cur_dir->directitem[i].sig n=0Jcur_dir->directitem[i].firstd isk=-1;strcpy(cur_dir->directitem[i].n ame,"");cur_dir->directitem[i]. next=-1;cur_dir->directitem[i].proper ty='0';cur_dir->directitem[i].size=OJreturn 0;}void dir(){int i;for(i=2;i<MSD+2;i++){if(cur_dir->directitem[i].fir stdisk!=-1) /*- 如果存在子目录-*/{prin tf("%s\t",cur_dir->direct item[i]. name);if(cur_dir->directitem[i].property=='0') /*- 文件-*/prin tf("%d\t\t\n",cur_dir->di rectitem[i].size);elseprintf("\t< 目录>\t\n");}}}int cd(char *n ame){int i,j,item;char *str;char *temp,*po in t,*po in t1; structdirect *temp_dir; temp_dir=cur_dir;str= name;if(!strcmp("\\", name)){cur_dir = root;strcpy(bufferdir,"Root:"); return 0;}temp = (char *)malloc(DIR_MAXSIZE*sizeof(char ));/* -最长路径名字分配空间-*/for(i=0;i<(i nt)strle n( str);i+ +)temp[i]=str[i];temp[i]='\0';for(j=0;j<MSD+2;j++) /*-查找该子目录是否在当前目录中-*/{if(!strcmp(temp_dir->directit em[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(".." ,n ame))void prin t() {if(cur_dir->directitem[j-1].sig n!=1) /*- 如果上级目录不是根目录 -*/{poi nt=strchr(bufferdir,'\\'); //查找字符串bufferdir 中首次出现 字符\的位置while(poi nt!=NULL) {point 仁point+1; /*- 减去'\'所占的空间,记录下次查找的 起始地址-*/poi nt=strchr(poi nt1,'\\'); }*(poi nt1-1)='\O';/*-将上一级目录删除-*/} }else {〃if(n ame[0] !='\\') bufferdir=strcat(bufferdir,"\\"); /*- 修改当前目录-*/bufferdir=strcat(bufferdir, name);}cur_dir=temp_dir; /*-将当前 目录确定下来-*/return 0; }void show() {prin tf("%s>",bufferdir);**********************************\n");*文 件 统计***********************、n");prin tf("*\t 命令格式说 明*\n");prin tf("*\tcd目录名 更 改当前目录 *\n");prin tf("*\tmkdir 目录名创建子目录*\n");prin tf("*\trmdir目录名删除子目录*\n");prin tf("*\tdir显 示当前目录的子目录 *\n");prin tf("*\tcreate 文件名创建文件 *\n");prin tf("*\tdel文件名删除文件 *\n");prin tf("*\tope n 文件名打开文件*\n");prin tf("*\tclose文件名关闭文件 *\n");prin tf("*\tread读 文件*\n");prin tf("*\twrite写 文件*\n");prin tf("*\texit 退 出系统 *\n");************************************\n")・}void mai n()FILE *fp; char ch;printf('\ *********************char a[100];char code[11][10];char n ame[10];int i,flag,r_size;char *con tect;con tect = (char *)malloc(MAX_WRITE*sizeof(char))Jif((fp=fopen( "disk.dat","rb") )==NULL){prin tf("You have not format,Do you want format?(y/n)"); scanf("%c",&ch);if(ch=='y'){in itfile();prin tf("Successfully format! \n");}else{return;}}en ter();prin t();show();strcpy(code[0],"exit");strcpy(code[1],"create");strcpy(code[2],"ope n");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");while(1){sca nf("%s",a);for(i=0;i<11;i++){if(!strcmp(code[i],a)) break;}switch(i){case 0: //退出文件系统free(contect); halt(); return;case 1: // 创建文件sca nf("%s", name); flag =create( name);if(flag==-1) { prin tf("Error:\n The length is too long !\n");} else if(flag==-2){prin tf("Error: \n The direct item is already full !\n");} else if(flag==-3){prin tf("Error: \n The number of openfile is too much !\n");} else if(flag==-4){prin tf("Error: \n The name is already in the direct !\n");}else if(flag==-5){prin tf("Error: \n show();The disk space is full!' n");Ibreak;} else case 3://关闭文件{ sca nf("%s", name);flag = close( name);prin tf("Successfully create a if(flag == -1)file! \n"); {} prin tf("Error:\nThe file is not ope ned ! \n ”);show(); }break; elsefcase 2://打开文件{sca nf("%s", name); prin tf("Successfullyclose fd = ope n(n ame); \n");if(fd == -1) }{ show();prin tf("Error: \n break;The ope n file not exit! \n ”);} case 4://写文件else if(fd == -2) if(fd ==-1){ {prin tf("Error: \n prin tf("Error:\nThe file have already opened! \n”);The file is not ope ned ! \n ”);} }else if(fd == -3) else{ {prin tf("Error: \n prin tf("PleaseThe number of open file is too much! in put the file con tect:");\n");} scan f("%s",co ntect);else if(fd == -4){ flag=write(fd ,con tect,strle n( prin tf("Error: \n con tect));It is a direct,can not open for read if(flag == 0)or write! \n"); {} else prin tf("Successfullywrite { \n");}prin tf("Successfully ope ned! else\n"); {}prin tf("Error:\n The disk size is not eno ugh! \n ”);}} show(); break;case 5://读文件if(fd ==-1){prin tf("Error:\nThe file is not ope ned ! \n ”);} else{flagread(fd,c on tect);if(flag == 0) {for(i=0;i<u_ope ntable.ope nitem[fd].size;i++){prin tf("%c",co ntect[i]);} prin tf("\t\n");}}show(); break;case 6://删除文件sca nf("%s",name); flag = del( name);if(flag == -1){prin tf("Error:\nThe file not exit! \n");} else if(flag == -2){prin tf("Error:\nThe file is opened,please first close it ! \n");} else if(flag == -3){prin tf("Error:\nThe delete is not file ! \n");} else{prin tf("Successfully delete! \n");} show(); break;case 7:// 创建子目录scanf("%s", name); flag =mkdir( name);if(flag == -1) { printf("Error:\nThe length of nameis to long! \n");} else if(flag == -2){prin tf("Error:\nThe direct item is already full !\n");} else if(flag == -3){prin tf("Error:\nThe nameis already in the direct ! \n");} else if(flag == -4){ prin tf("Error: \n '..' or '.' can not as the n ame of the direct!\n");} else if(flag == -5){prin tf("Error: \n The disk space is full!' n");} else if(flag == 0){prin tf("Successfullymak edircet! \n");} show(); break;case 8://删除子目录sca nf("%s",name); flag = rmdir( name);if(flag == -1) { printf("Error:\n The direct is not exist! \n");} else if(flag == -2){prin tf("Error:\nThe direct has son direct ,please first remove the sondircct!\n");} else if(flag == -3){prin tf("Error:\nThe remove is not direct ! \n ”);} else if(flag == 0){prin tf("Successfully remove dircet! \n");}show(); break;case 9:// 显示当前子目录dir();show(); break;case 10://更改当前目录scanf("%s", name); flag = cd(name); if(flag == -1) {prin tf("Error:\nThe path no correct!\n");} else if(flag == -2){prin tf("Error:\nThe ope ned is not direct!\n");}show(); break;default:prin tf("\n Error!\ncomma nd is wrong! \n");show();}}}The5.程序运行截图:oot: >mkdii* m uccessfull^f nake direct! loot: >cd n :oot: xui>ci'ea ,te 1 uccessFullsf create a file! :oot: \m>writelease input the file connect:hello* uccessfullsf write! :oat: \n>t i ead elloT:oot : Xn>close 1uccessf 11II5P closed*00t :\n>exitress an9 key to cont inue6.实验总结通过这一次计算机操作系统的上机实验,使我对不同环境下的操作系统有了 进一步的了解,使我学到了很多关于 Linux 的操作和相关知识。

操作系统课程设计-模拟一个简单二级文件管理系统

操作系统课程设计-模拟一个简单二级文件管理系统

模拟一个简单二级文件管理系统设计目的:通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部功能和实现过程的理解。

设计内容:模拟一个简单二级文件管理系统一、实验内容描述1 实验目标本实验的目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现.2 实验要求为DOS系统设计一个简单的二级文件系统.要求做到以下几点:①可以实现下列命令:login 用户登录dir 列文件目录create 创建文件delete 删除文件open 打开文件close 关闭文件read 读文件write 写文件②列目录时要列出文件名、物理地址、保护码和文件长度.③源文件可以进行读写保护.二、程序主要内容1设计思路程序中要求每个用户在登陆后才可对其拥有的文件进行操作,用户对于其他用户的文件无操作权.文件操作包括浏览、创建、删除、打开、关闭、阅读、写入、修改模式.其他操作包括新建用户、帮助、用户登入、用户登出、退出系统.在程序文件夹下有个名为“file”的系统根目录,此目录下包括:一个名为“mfd”的文件,记录所有注册过的帐号及密码;用户文件,以用户名作为文件名,内容为其拥有的文件名及属性;一个名为“keiji”的文件夹.“keiji”文件夹中包括:“file.p”指针文件,记录所有已用的物理地址;一些以物理地址为名的文件,内容为文件内容.2 数据结构file结构体系统文件数据结构:fpaddrint,文件的物理地址、flengthint,文件长度、fmodeint,文件模式0.只读;1.可写;2.可读写;3.保护、fname[]char,文件名;filemode结构体文件状态数据结构:isopenint,文件当前状态,0.关闭;1.打开、modeint,文件模式0.只读;1.可写;2.可读写;3.初始化;user结构体用户信息数据结构:uname[]char,用户名、upassword[]char,用户密码;userfile结构体用户文件数据结构:uname[]char,用户名、ufile[]file,用户拥有的文件数组.代码:#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <time.h>#include <string.h>#define MaxUser 100 //定义最大MDF主目录文件#define MaxDisk 512*1024 //模拟最大磁盘空间#define commandAmount 12 //对文件操作的指令数//存储空间管理有关结构体和变量char disk[MaxDisk]; //模拟512K的磁盘存储空间typedef struct distTable //磁盘块结构体{int maxlength;int start;int useFlag;distTable *next;}diskNode;diskNode *diskHead;struct fileTable //文件块结构体{char fileName[10];int strat; //文件在磁盘存储空间的起始地址int length; //文件内容长度int maxlength; //文件的最大长度char fileKind[3]; //文件的属性——读写方式struct tm *timeinfo;bool openFlag; //判断是否有进程打开了该文件//fileTable *next;};//两级目录结构体typedef struct user_file_directory //用户文件目录文件UFD {//char fileName[10];fileTable *file;user_file_directory *next;}UFD;//UFD *headFile;typedef struct master_file_directory //主文件目录MFD{char userName[10];char password[10];UFD *user;}MFD;MFD userTable[MaxUser];int used=0; //定义MFD目录中用已有的用户数//文件管理void fileCreate(char fileName[],int length,char fileKind[]); //创建文件void fileWrite(char fileName[]); //写文件void fileCat(char fileName[]); //读文件void fileRen(char fileName[],char rename[]); //重命名文件void fileFine(char fileName[]); //查询文件void fileDir(char UserName[]); //显示某一用户的所有文件void fileClose(char fileName[]); //关闭已打开的文件void fileDel(char fileName[]); //删除文件void chmod(char fileName[],char kind[]); //修改文件的读写方式int requestDist(int &startPostion,int maxLength); //磁盘分配查询void initDisk(); //初始化磁盘void freeDisk(int startPostion); //磁盘空间释放void diskShow(); //显示磁盘使用情况//用户管理void userCreate();int login();int userID=-1; //用户登录的ID号,值为-1时表示没有用户登录int main(){char order[commandAmount][10];strcpy(order[0],"create");strcpy(order[1],"rm");strcpy(order[2],"cat");strcpy(order[3],"write");strcpy(order[4],"fine");strcpy(order[5],"chmod");strcpy(order[6],"ren");strcpy(order[7],"dir");strcpy(order[8],"close");strcpy(order[9],"return");strcpy(order[10],"exit");strcpy(order[11],"df");char command[50],command_str1[10],command_str2[10],command_str3[5],command_str4[3];int i,k,j;int length;initDisk(); //初始化磁盘for(i=0;i<MaxUser;i++) //初始化用户UFD目录文件的头指针{userTable[i].user=(UFD *)malloc(sizeof(UFD));userTable[i].user->next=NULL;}while(1){printf("********************************************\n");printf(" 1、Creat user\n");printf(" 2、login\n");printf("********************************************\n");printf("Please chooce the function key:>");int choice;scanf("%d",&choice);if(choice==1) userCreate();else if(choice==2) userID=login();else printf("您的输入有误,请重新选择\n");while(userID!=-1){fflush(stdin);printf("———————————————————————————————————————\n ");printf(" create-创建格式:create a1 1000 rw,将创建名为a1,长度为1000字节可读可写的文件\n");printf(" rm-删除格式:rm a1,将删除名为a1的文件\n");printf(" cat-查看文件内容格式:cat a1,显示a1的内容\n");printf(" write-写入格式:write a1\n");printf(" fine-查询格式:fine a1 ,将显示文件a1的属性\n");printf(" chmod-修改格式:chmod a1 r,将文件a1的权限改为只读方式\n");printf(" ren-重命名格式:ren a1 b1 ,将a1改名为b1\n");printf(" dir-显示文件格式:dir aaa,将显示aaa用户的所有文件\n");printf(" df-显示磁盘空间使用情况格式:df\n");printf(" close-关闭文件格式:close a1,将关闭文件a1\n");printf(" return-退出用户,返回登录界面\n");printf(" exit-退出程序\n");printf("————————————————————————————————————————\n");printf("please imput your command:>");gets(command);int select;for(i=0;command[i]!=' '&&command[i]!='\0';i++) //command_str1字符串存储命令的操作类型command_str1[i]=command[i];k=i;command_str1[k]='\0';for(i=0;i<commandAmount;i++){if(!strcmp(command_str1,order[i])){select=i;break;}}if(i==commandAmount){printf("您输入的命令有误,请重新输入\n");continue;}for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++) //commmand_str2字符串存储文件名或用户名command_str2[k]=command[i];command_str2[k]='\0';k=i;switch(select){case 0:for(i=k+1,k=0;command[i]!=' ';i++,k++)command_str3[k]=command[i];command_str3[k]='\0';k=i;j=1;length=0; //初始化文件长度for(i=strlen(command_str3)-1;i>=0;i--) //把字符串转换为十进制{length+=(command_str3[i]-48)*j;j*=10;}for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++)command_str4[k]=command[i];command_str4[k]='\0';fileCreate(command_str2,length,command_str4);break;case 1:fileDel(command_str2);break;case 2:fileCat(command_str2);break;case 3:fileWrite(command_str2);break;case 4:fileFine(command_str2);break;case 5:for(i=k+1,k=0;command[i]!=' '&&command[i]!='\0';i++,k++)command_str3[k]=command[i];command_str3[k]='\0';chmod(command_str2,command_str3);break;case 6:for(i=k+1,k=0;command[i]!='\0';i++,k++)command_str3[k]=command[i];command_str3[k]='\0';fileRen(command_str2,command_str3);break;case 7:fileDir(command_str2);break;case 8:fileClose(command_str2);break;case 9:UFD *p;for(p=userTable[userID].user->next;p!=NULL;p=p->next) //退出用户之前关闭所有打的文件if(p->file->openFlag)p->file->openFlag=false;system("cls");userID=-1;break;case 10:exit(0);break;case 11:diskShow();break;}}}return 0;}void userCreate(){char c;char userName[10];int i;if(used<MaxUser){printf("请输入用户名:");for(i=0;c=getch();i++){if(c==13) break;elseuserName[i]=c;printf("%c",c);}userName[i]='\0';for(i=0;i<used;i++){if(!strcmp(userTable[i].userName,userName)){printf("\n");printf("该用户名已存在,创建用户失败\n");system("pause");return;}}strcpy(userTable[used].userName,userName);printf("\n");printf("请输入密码:");for(i=0;c=getch();i++){if(c==13) break;elseuserTable[used].password[i]=c;printf("*");}userTable[userID].password[i]='\0';printf("\n");printf("创建用户成功\n");used++;system("pause");}else{printf("创建用户失败,用户已达到上限\n");system("pause");}fflush(stdin);}int login(){char name[10],psw[10];char c;int i,times;printf("请输入用户名:");for(i=0;c=getch();i++){if(c==13) break;elsename[i]=c;printf("%c",c);}name[i]='\0';for(i=0;i<used;i++){if(!strcmp(userTable[i].userName,name))break;}if(i==used){printf("\n您输入的用户名不存在\n");system("pause");return -1;}for(times=0;times<3;times++){memset(psw,'\0',sizeof(psw));printf("\n请输入密码:");for(i=0;c=getch();i++){if(c==13) break;elsepsw[i]=c;printf("*");}printf("\n");for(i=0;i<used;i++){if(!strcmp(psw,userTable[i].password)){printf("用户登录成功\n");system("pause");break;}}if(i==used){printf("您输入的密码错误,您还有%d次输入机会\n",2-times);if(times==2) exit(0);}else break;}fflush(stdin);return i;}void initDisk(){diskHead=(diskNode *)malloc(sizeof(diskNode));diskHead->maxlength=MaxDisk;diskHead->useFlag=0;diskHead->start=0;diskHead->next=NULL;}int requestDist(int &startPostion,int maxLength){int flag=0; //标记是否分配成功diskNode *p,*q,*temp;p=diskHead;while(p){if(p->useFlag==0&&p->maxlength>maxLength){startPostion=p->start;q=(diskNode *)malloc(sizeof(diskNode));q->start=p->start;q->maxlength=maxLength;q->useFlag=1;q->next=NULL;diskHead->start=p->start+maxLength;diskHead->maxlength=p->maxlength-maxLength;flag=1;temp=p;if(diskHead->next==NULL) diskHead->next=q;else{while(temp->next) temp=temp->next;temp->next=q;}break;}p=p->next;}return flag;}void fileCreate(char fileName[],int length,char fileKind[]){//int i,j;time_t rawtime;int startPos;UFD *fileNode,*p;for(p=userTable[userID].user->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName)){printf("文件重名,创建文件失败\n");system("pause");return;}}if(requestDist(startPos,length)){fileNode=(UFD *)malloc(sizeof(UFD));fileNode->file=(fileTable *)malloc(sizeof(fileTable)); //这一步必不可少,因为fileNode里面的指针也需要申请地址,否则fileNode->file指向会出错strcpy(fileNode->file->fileName,fileName);strcpy(fileNode->file->fileKind,fileKind);fileNode->file->maxlength=length;fileNode->file->strat=startPos;fileNode->file->openFlag=false;time(&rawtime);fileNode->file->timeinfo=localtime(&rawtime);fileNode->next=NULL;if(userTable[userID].user->next==NULL)userTable[userID].user->next=fileNode;else{p=userTable[userID].user->next;while(p->next) p=p->next;p->next=fileNode;}printf("创建文件成功\n");system("pause");}else{printf("磁盘空间已满或所创建文件超出磁盘空闲容量,磁盘空间分配失败\n");system("pause");}}void freeDisk(int startPostion){diskNode *p;for(p=diskHead;p!=NULL;p=p->next){if(p->start==startPostion)break;}p->useFlag=false;}void fileDel(char fileName[]){UFD *p,*q,*temp;q=userTable[userID].user;p=q->next;while(p){if(!strcmp(p->file->fileName,fileName)) break;else{p=p->next;q=q->next;}}if(p){if(p->file->openFlag!=true) //先判断是否有进程打开该文件{temp=p;q->next=p->next;freeDisk(temp->file->strat); //磁盘空间回收free(temp);printf("文件删除成功\n");system("pause");}else{printf("该文件已被进程打开,删除失败\n");system("pause");}}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileCat(char fileName[]){int startPos,length;int k=0;UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){startPos=p->file->strat;length=p->file->length;p->file->openFlag=true; //文件打开标记printf("*****************************************************\n");for(int i=startPos;k<length;i++,k++){if(i%50==0) printf("\n"); //一行大于50个字符换行printf("%c",disk[i]);}printf("\n\n*****************************************************\n");printf("%s已被read进程打开,请用close命令将其关闭\n",p->file->fileName);system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileWrite(char fileName[]){UFD *p,*q;q=userTable[userID].user;int i,k,startPos;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){if(!strcmp(p->file->fileKind,"r")) //判断文件类型{printf("该文件是只读文件,写入失败\n");system("pause");return;}char str[500];printf("please input content:\n");gets(str);startPos=p->file->strat;p->file->openFlag=true; //文件打开标记p->file->length=strlen(str);if(p->file->length>p->file->maxlength){printf("写入字符串长度大于该文件的总长度,写入失败\n");system("pause");return;}for(i=startPos,k=0;k<(int)strlen(str);i++,k++)disk[i]=str[k];printf("文件写入成功,请用close命令将该文件关闭\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileFine(char fileName[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){printf("********************************************\n");printf("文件名:%s\n",p->file->fileName);printf("文件长度:%d\n",p->file->maxlength);printf("文件在存储空间的起始地址:%d\n",p->file->strat);printf("文件类型:%s\n",p->file->fileKind);printf("创建时间:%s\n",asctime(p->file->timeinfo));printf("********************************************\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void chmod(char fileName[],char kind[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){strcpy(p->file->fileKind,kind);printf("修改文件类型成功\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileRen(char fileName[],char name[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){while(q->next){if(!strcmp(q->next->file->fileName,name)){printf("您输入的文件名已存在,重命名失败\n");system("pause");return;}q=q->next;}strcpy(p->file->fileName,name);printf("重命名成功\n");system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}void fileDir(char userName[]){UFD *p;int i,k;for(i=0;i<MaxUser;i++){if(!strcmp(userTable[i].userName,userName)){k=i;break;}}if(i==MaxUser){printf("没有找到该用户,请检查输入用户名是否正确\n");system("pause");return;}else{p=userTable[k].user->next;printf("******************************************************************************* *\n");printf("文件名文件长度文件在磁盘的起始地址文件类型创建时间\n");for(;p!=NULL;p=p->next)printf("%s %d %d %s %s",p->file->fileName,p->file->maxlength,p->file->strat,p->file->fileKind,asctime(p->file->timeinfo));printf("******************************************************************************* *\n");system("pause");}}void diskShow(){diskNode *p;int i=0,unusedDisk=0;printf("***************************************************************************\n");printf(" 盘块号起始地址容量(bit) 是否已被使用\n");for(p=diskHead;p!=NULL;p=p->next,i++){if(p->useFlag==false) unusedDisk+=p->maxlength;printf(" %d %d %d %d \n",i,p->start,p->maxlength,p->useFlag);}printf("***************************************************************************\n");printf("磁盘空间总容量:512*1024bit 已使用:%dbit 末使用:%dbit\n\n",MaxDisk-unusedDisk,unusedDisk);system("pause");}void fileClose(char fileName[]){UFD *p,*q;q=userTable[userID].user;for(p=q->next;p!=NULL;p=p->next){if(!strcmp(p->file->fileName,fileName))break;}if(p){p->file->openFlag=false;printf("%s文件已关闭\n",p->file->fileName);system("pause");}else{printf("没有找到该文件,请检查输入的文件名是否正确\n");system("pause");}}运行结果视图:(略)。

文件系统模拟

文件系统模拟

文件管理系统模拟一、实验目的用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。

从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。

二、实验内容和要求要求设计一个 n个用户的文件系统,每次用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有Create、delete、open、close、read、write等命令(至少4条)。

三算法及数据结构1、程序流程图main函数(即主目录下的操作)2.数据结构struct mfd{ //主文件目录char uname[12]; //用户名struct ufd *flink; //文件目录指针struct mfd *unext;}*mready=null,*mp,*ff;typedef struct mfd MFD;struct ufd{ //用户文件目录char fname[12]; //文件名int pcode ; //保护码int length; //文件长度struct ufd* fnext;}*uready=null,*np;typedef struct ufd UFD;struct afd{ //运行文件目录char openfname[12];//打开文件名int openpcode; //打开保护码int rpoint; //读指针int wpoint; //写指针}*arunning=null,*ap;typedef struct afd AFD;(1)创建文件void createfile(MFD *f) /*********************创建文件************************/{UFD *fp;fp=f->flink;if(fp==null){np=getpch(UFD);printf("创建文件");printf("\n\t\t\t\t文件名:");scanf("%s",np->fname);printf("\t\t\t\t保护码:");scanf("%d",&np->pcode);printf("\t\t\t\t文件长:");scanf("%d",&np->length);f->flink=np;np->fnext=null;}else{while(fp->fnext!=null){ fp=fp->fnext;}np=getpch(UFD);printf("创建文件");printf("\n\t\t\t\t文件名:");scanf("%s",np->fname);printf("\t\t\t\t保护码:");scanf("%d",&np->pcode);printf("\t\t\t\t文件长:");scanf("%d",&np->length);if(checkfile(np)) printf("\t\t\t\t相同文件已经存在,无法创建!\n"); else{fp->fnext=np;np->fnext=null;}}//fprint(f);}(2)删除文件/************************删除文件***************************/void fdelete(MFD *f){UFD *fp,*fq;char dename[12];printf("删除文件");fp=f->flink;if(fp==null){printf("\t\t\t\t没有文件可供删除!\n");}else{printf("\n\t\t\t\t文件名:");scanf("%s",dename);if(arunning!=null&&strcmp(dename,arunning->openfname)==0) { printf("\t\t\t\t文件正在使用中,不能删除!\n");goto end;}if(strcmp(dename,fp->fname)==0) {printf("\t\t\t\t删除文件<%s>成功!\n",dename);f->flink=fp->fnext;}else{fq=fp;fp=fp->fnext;if(fp==NULL)printf("\t\t\t\t文件名不存在\n");while(fp!=null){ if(strcmp(dename,fp->fname)==0){fq->fnext=fp->fnext;printf("\n\t\t\t\t删除文件<%s>成功!\n",dename);break;}fq=fq->fnext;fp=fp->fnext;if(fp==NULL)printf("\n\t\t\t\t文件名不存在\n");}}}end:;//fprint(f);}(3)打开文件/***********************打开文件***************************/void open(MFD *f){UFD *fp;char oname[12];int pc;fp=f->flink;if(fp==null){printf("\n\t\t\t\t没有文件可供打开!\n");}else{printf("\n\t\t\t\t文件名:");scanf("%s",oname);printf("\t\t\t\t保护码:");scanf("%d",&pc);while(fp!=null) {if((strcmp(oname,fp->fname)==0)&&(fp->pcode==pc)){ap=getpch(AFD);strcpy(ap->openfname,fp->fname);ap->openpcode=fp->pcode;ap->rpoint=0;ap->wpoint=fp->length;if(arunning==null) {arunning=ap;nowopenf(arunning);}else printf("\t\t\t\t正在打开文件,不允许同时运行两个文件!\n");break;}fp=fp->fnext;}if(arunning==null) printf("\t\t\t\t文件不存在!\n");}(4)写文件/********************写入文件**********************/void write(MFD *f){int len,i;UFD *fp;fp=f->flink;printf("写入文件");open(f);if((arunning->openpcode==1)||(arunning->openpcode==3)) {printf("\t\t\t\t文件不可写!\n");close();}else{ printf("\t\t\t\t写入内容长度:");scanf("%d",&len);printf("\t\t\t\t写入文件中....\n\t\t\t\t\t\t");for(i=arunning->wpoint;i<(arunning->wpoint+len);i++){printf("> ");Sleep(200);}arunning->wpoint=arunning->wpoint+len;while(fp!=null){ if(strcmp(arunning->openfname,fp->fname)==0){fp->length=arunning->wpoint;break;}fp=fp->fnext;}printf("\n\t\t\t\t写入完毕!\n");close();}}(5)读文件/*******************读取文件***********************/void read(MFD *f){printf("读取文件");open(f);if(arunning==null) goto end;if(arunning->openpcode==3) printf("\t\t\t\t文件不可读!\n");else{printf("\t\t\t\t读取文件中....\n");for((arunning->rpoint)=0;(arunning->rpoint)<(arunning->wpoint);(arunning-> rpoint)++){printf("\t\t\t\t\t\t>>>>>>>");Sleep(200);}printf("\n\t\t\t\t读取完毕!\n");}close();end:;}(6)插入用户到用户队列/*****************插入用户到用户队列*******************/void uinsert(){MFD *first,*second;if(mready==null){mp->unext=mready;mready=mp;}else{ first=mready;second=first->unext;while(second!=null){ first=first->unext;second=second->unext;}first->unext=mp;}usernum=usernum+1;//增加一个用户 }五、实验结果及分析1、运行结果(要求截图)(能动态说明执行结果)用户一级操作界面创建用户用户登录后二级操作界面创建文件a、b、c、d查看文件信息删除文件d 读取不存在文件r打开文件a 删除正在使用中的文件a读取文件b 写入不可写文件c写入可写文件b 查看文件信息关闭文件打开文件后关闭文件退回上一级界面2、实验结果的分析及说明根据界面提示操作,特别说明,对于命令操作create、delete、open、close、read、write用了选择数字按键操作。

实验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. 实验目的本实验旨在通过模拟操作系统的文件管理系统,深入理解操作系统中文件的组织结构、文件的创建、读写和删除操作,以及文件系统的管理策略。

2. 实验背景操作系统是计算机系统中的核心软件,负责管理计算机的资源并提供用户与计算机硬件之间的接口。

文件管理系统是操作系统的重要组成部分,用于管理计算机中的文件和目录结构,提供文件的读写、创建和删除等操作。

3. 实验环境本实验可以在任何支持操作系统模拟的计算机上进行,如使用虚拟机软件搭建的操作系统环境或在线操作系统模拟器。

4. 实验步骤4.1 文件系统初始化在模拟实验开始之前,需要对文件系统进行初始化。

可以选择创建一个空的文件系统或使用预先定义好的文件系统。

4.2 文件的创建在文件系统中创建一个新文件。

可以指定文件的名称、大小、属性等信息。

文件创建成功后,可以在文件系统中查看该文件的相关信息。

4.3 文件的读取选择一个已经存在的文件,并从文件系统中读取该文件的内容。

可以通过指定文件的路径或名称来进行读取操作。

读取文件时,可以选择按字节、按行或按块进行读取。

4.4 文件的写入选择一个已经存在的文件,并向该文件中写入内容。

可以选择覆盖原有内容或在文件末尾追加新内容。

写入文件时,可以选择按字节、按行或按块进行写入。

4.5 文件的删除选择一个已经存在的文件,并从文件系统中删除该文件。

删除文件后,文件系统中将不再存在该文件的相关信息。

5. 实验结果分析在完成实验步骤后,可以对实验结果进行分析和总结。

可以比较不同文件的读写操作所消耗的时间和资源,评估不同文件系统管理策略的性能优劣。

6. 实验注意事项6.1 在进行文件操作时,务必注意文件的权限和保护机制,避免误操作导致数据丢失或系统崩溃。

6.2 在进行文件读写操作时,要注意文件的大小和系统资源的限制,避免因为文件过大或系统资源不足而导致操作失败。

6.3 在进行文件删除操作时,要谨慎操作,避免误删重要文件或系统关键文件,导致系统无法正常运行。

简单文件系统的实现实验报告

简单文件系统的实现实验报告

操作系统课程设计报告简单文件系统的实现专业:班级:姓名:学号:老师:一、课程设计的目的1. 通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部数据结构、功能以及实现过程的理解。

二、课程设计要求1. 在内存中开辟一个虚拟磁盘空间作为文件存储分区,在其上实现一个简单的基于多级目录的单用户单任务系统中的文件系统。

在退出该文件系统的使用时,应将该虚拟文件系统以一个Windows 文件的方式保存到磁盘上,以便下次可以再将它恢复到内存的虚拟磁盘空间中。

2文件存储空间的分配可采用显式链接分配或其他的办法。

3空闲磁盘空间的管理可选择位示图或其他的办法。

如果采用位示图来管理文件存储空间,并采用显式链接分配方式,那么可以将位示图合并到FAT中。

文件目录结构采用多级目录结构。

为了简单起见,可以不使用索引结点,其中的每个目录项应包含文件名、物理地址、长度等信息,还可以通过目录项实现对文件的读和写的保护。

要求提供以下有关的操作命令:my_format:对文件存储器进行格式化,即按照文件系统的结构对虚拟磁盘空间进行布局,并在其上创建根目录以及用于管理文件存储空间等的数据结构。

my_mkdir:用于创建子目录。

my_rmdir:用于删除子目录。

my_ls:用于显示目录中的内容。

my_cd:用于更改当前目录。

my_create:用于创建文件。

my_open:用于打开文件。

my_close:用于关闭文件。

my_write:用于写文件。

my_read:用于读文件。

my_rm:用于删除文件。

my_exitsys:用于退出文件系统。

三、程序的设计细想和框图1.打开文件函数fopen()(1)格式:FILE *fopen(const char *filename,const char *mode)(2)功能:按照指定打开方式打开指定文件。

(3)输入参数说明:filename:待打开的文件名,如果不存在就创建该文件。

文件系统模拟实验(C-实验教材)

文件系统模拟实验(C-实验教材)

文件系统实验1.1实验目的和要求1.1.1实验目的通常把文件与管理信息资源的管理程序的集合称为文件系统,它是操作系统中负责存取和管理信息资源的模块,采用统一的方法管理用户信息和系统信息的存储、检索、更新、共享和保护,并为用户提供一套行之有效的文件使用及操作方法。

本实验利用高级语言编写程序模拟文件系统,了解文件系统的基本结构和文件的各种操作方法,加深理解文件系统的内部功能及内部实现,从而帮助学生对各种文件操作命令的实质内容和执行过程有比较深入的了解。

1.1.2实验要求1.采用高级语言编写程序模拟文件系统,文件系统采用多级目录结构,实现对文件和目录的创建、删除、重命名、变更权限、显示文件内容、修改文件内容等操作。

2.撰写实验报告,报告应包含以下内容:(1)实验目的;(2)实验内容;(3)设计思路;(4)程序流程图;(5)程序中主要数据结构和函数说明;(6)带注释的源程序代码;(7)程序运行结果及分析(8)实验收获与体会1.2预备知识1.2.1文件和文件系统1.文件概念现代计算机系统中都配置了外存,大量的程序和数据以文件的形式存放在外存。

如果由用户直接管理文件,不仅要求用户熟悉外存特性,了解各种文件的属性,以及它们在外存上的位置,而且多用户环境下还必须能保持数据的安全性和一致性,这是用户不能胜任的。

因而,现代操作系统中都配备文件系统,以适应系统资源管理和用户使用信息的需要。

文件是指由创建者所定义的、具有文件名的一组相关元素的集合。

用户通过文件名就可对文件进行访问,文件名是由字母或数字组成的字母或数字串,其格式和长度都因系统而异。

操作系统提供文件系统的优点有:(1)便于用户使用。

(2)文件安全可靠。

(3)系统能有效利用存储空间,优化安排不同属主文件的位置。

(4)文件系统还能提供文件共享功能。

2.文件命名在不同的操作系统中对文件名的规定有所不同,文件名的格式和长度因系统而异。

一般来说,文件名由文件名和扩展名两部分组成,前者用于标识文件,后者用于区分文件类型,中间用“.”分割开来,它们都是字母或数字所组成的字母数字串。

操作系统试验——模拟文件管理系统

操作系统试验——模拟文件管理系统

模拟文件管理系统一、实验内容1.基本要求:编写一程序,模拟一个简单的文件管理系统。

树型结构,目录下可以是目录,也可以是文件。

在此文件管理系统,可实现的操作有:改变目录:格式:cd <目录名>显示目录:格式:dir[<目录名>]创建目录:格式:md <目录名>删除目录:格式:rd<目录名>新建文件:格式:edit<文件名>删除文件:格式:del<文件名>退出文件系统:exit2.目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开3.功能具体描述:改变目录:改变当前工作目录,目录不存在是给出出错信息显示目录:显示指定目录下或当前目录下所有文件和一级目录(选做:带/s 参数的dir命令,显示所有子目录)创建目录:在指定路径或当前路径下创建指定目录。

重名时给出出错信息。

删除目录:删除指定目录下所有文件和子目录。

要删目录不空时,要给出提示是否要删除。

创建文件:创建指定名字的文件,只要创建表示文件的节点即可,内容及大小不考虑。

删除文件:删除指定文件,不存在时给出出错信息。

退出文件系统:exit4.总体流程:初始化文件目录输出提示符,等待接受命令,分析键入的命令;对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令。

直到键入exit退出为止。

二、数据结构设计StructFileNode{Char filename[FILENAME_LEN];//文件名/目录名Int isdir ;//目录、文件的识别标志Int i_nlink;//文件链接数Int adr;//文件的地址Struct FileNode *parent,*child;//指向父亲的指针和左孩子的指针Struct FileNode *sibling_prev,*sibling_next;//指向前一个兄弟的指针和后一个兄弟的指针。

}三、算法设计3.1 功能模块图3.2算法思路3.2.1实现方法bool spile(char *str,char *cmdstr,char *filestr);//切割字符串bool shell(char *str);//用来解释命令bool errorp(int id);ﻩﻩ//打印错误提示bool boot(); ﻩ//启动初始化filenode* find(char*str,filenode *_root); //递归对目录树进行查找bool cdexc(char *str);ﻩﻩ//执行cd命令booldirexc(char *str); //执行dir命令bool mdexc(char *str); ﻩ//执行md命令bool editexc(char *str);//执行edit命令bool delexc(char *str,filenode *fcur,bool mode,bool dir);//执行del命令bool exitexc(); ﻩﻩﻩ//退出filenode* createnode(char *str,bool_isdir,int _adr,filenode*_par);//新建对象节点函数调用图3.2.2 设计思想建立一刻目录树,根据输入的命令字符串,对该目录树进行增删等操作。

模拟文件系统实验报告

模拟文件系统实验报告

操作系统大型试验实验报告姓名:XX班级:软件工程110x学号:201126630xxx一、名称操作系统大型试验。

二、目的用C++编写出一个简单的模拟文件系统,实现目录的添加、删除、重命名,文件的添加、删除、重命名、文件和目录、文件的拷贝。

三、要求开发工具:word,vc win32api1.设计和实现一个简单的文件系统,要求包括目录、普通文件和文件的存储2.文件系统的目录结构采用类似Linux的树状结构;3.要求模拟的操作包括:a)目录的添加、删除、重命名;b)目录的显示(列表)c)文件的添加、删除、重命名d)文件和目录的拷贝4.用户进入时显示可用命令列表;用户输入help时显示所有命令的帮助文档;输入某个命令+?时显示该条命令的使用说明5.用户输入exit时退出该系统6.实验实现基于windows平台;7.实验开发语言可以选用C/c++等四、设计1.主要思路说明本模拟系统通过一个大小固定的数组要代表物理盘块,假设共有1024块,新增目录占一块,新增文件占一块,文件中可输入内容,内容假设定义为5个字符占一块,超出则应新申请空间。

模拟物理盘块的数组中,数组内容为-99代表改物理盘块内容为空,可使用,其他数字均代表该物理盘块被占用,其中-3代表是占用文件的末结点,其他整数代表是文件内容的下一个寻址下标,另有一个string类型的数组来存储内容,模拟文件写入了对应下标的物理盘块中。

设置了一个全局指针指向根结点,一个全局指针指向当前操作目录。

搜索空白物理盘块时采用顺序搜索物理盘块数组。

存储形式主要采用类似二叉树结构,如目录为根,目录下的第一个文件或目录存在根的子节点,目录下的其他文件或目录存在第一个文件或目录的兄弟节点,以此类推。

本程序仅seperate()函数使用现成代码,此函数功能为将输入命令串分离,仅仅起到美观作用,其余所有代码均为原创!2.申优功能:1)能实现动态增长,即当输入文件的内容大小大于分配的模拟物理盘块时系统能够自动寻找空物理盘块并分配,将超出的内容保存在新的物理盘块中,若超出模拟磁盘大小,则超出部分不保存且返回提示。

文件系统模拟实验(C-实验教材)

文件系统模拟实验(C-实验教材)

文件系统实验1.1实验目的和要求1.1.1实验目的通常把文件与管理信息资源的管理程序的集合称为文件系统,它是操作系统中负责存取和管理信息资源的模块,采用统一的方法管理用户信息和系统信息的存储、检索、更新、共享和保护,并为用户提供一套行之有效的文件使用及操作方法。

本实验利用高级语言编写程序模拟文件系统,了解文件系统的基本结构和文件的各种操作方法,加深理解文件系统的内部功能及内部实现,从而帮助学生对各种文件操作命令的实质内容和执行过程有比较深入的了解。

1.1.2实验要求1.采用高级语言编写程序模拟文件系统,文件系统采用多级目录结构,实现对文件和目录的创建、删除、重命名、变更权限、显示文件内容、修改文件内容等操作。

2.撰写实验报告,报告应包含以下内容:(1)实验目的;(2)实验内容;(3)设计思路;(4)程序流程图;(5)程序中主要数据结构和函数说明;(6)带注释的源程序代码;(7)程序运行结果及分析(8)实验收获与体会1.2预备知识1.2.1文件和文件系统1.文件概念现代计算机系统中都配置了外存,大量的程序和数据以文件的形式存放在外存。

如果由用户直接管理文件,不仅要求用户熟悉外存特性,了解各种文件的属性,以及它们在外存上的位置,而且多用户环境下还必须能保持数据的安全性和一致性,这是用户不能胜任的。

因而,现代操作系统中都配备文件系统,以适应系统资源管理和用户使用信息的需要。

文件是指由创建者所定义的、具有文件名的一组相关元素的集合。

用户通过文件名就可对文件进行访问,文件名是由字母或数字组成的字母或数字串,其格式和长度都因系统而异。

操作系统提供文件系统的优点有:(1)便于用户使用。

(2)文件安全可靠。

(3)系统能有效利用存储空间,优化安排不同属主文件的位置。

(4)文件系统还能提供文件共享功能。

2.文件命名在不同的操作系统中对文件名的规定有所不同,文件名的格式和长度因系统而异。

一般来说,文件名由文件名和扩展名两部分组成,前者用于标识文件,后者用于区分文件类型,中间用“.”分割开来,它们都是字母或数字所组成的字母数字串。

文件系统存储空间管理模拟实验报告

文件系统存储空间管理模拟实验报告

课程名称计算机操作系统实验名称文件系统存储空间管理模拟姓名____________________ 学号_______________________________ 专业班级_________________ 实验日期____________________________ 成绩______________________ 指导老师_________________________一、实验目的根据提出的文件分配和释放请求,动态显示磁盘空闲空间的态以及文件目录的变化,以位示图和索引分配为例:每次执行请求后要求显示或打印位示图的修改位置、分配和回收磁盘的物理块地址、更新的位示图、目录。

二、实验原理用数组表示位示图,其中的每一位对应磁盘一个物理块的状态,0表示、空闲,1表示分配;当请求分配一个磁盘块时,寻找到数组中为0的位,计算相对磁盘块号,并计算其在磁盘中的物理地址(柱面号、磁道号、物理块号),并将其状态由0变到1。

当释放某一物理块时,已知其在磁盘中的物理地址,计算其相对磁盘块号,再找到位示图数组中的相应位,将其状态由1变为0。

三、主要仪器设备PC机(含有VC)四、实验内容与步骤实验内容:1.模拟文件空间分配、释放过程,可选择连续分配、链式分配、索引分配方法;2.文件空闲空间管理,可采用空白块链、空白目录、位示图方法;步骤如下:1.输入磁盘基本信息参数,计算位示图大小,并随机初始化位示图;(1)磁盘基本信息:磁盘柱面数m,每柱面磁道数p,每磁道物理块数q;(2)假设采用整数数组存放位示图,则数组大小为:Size= ceil ((柱面数*每柱面磁道数*每磁道物理块数)/ (sizeof(int)*8 ))(3)申请大小为size的整数数组map,并对其进行随机初始化。

例如:假设m=2, p=4, q=8, 共有64个磁盘块,若sizeof(int)=2, 则位示图大小为4,map[4]如下:位示图中每一位对应的相对磁盘块号如下图,磁盘块号由小到大对应于数组的低地址到高地址位上。

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

简单文件系统模拟实验实验目的通过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统功能和实现过程的理解。

实验内容▪在内存中开辟一个虚拟磁盘空间作为文件存储器,在其上实现一个简单的单用户文件系统。

在退出这个简单文件系统时,应将该虚拟文件系统保存到磁盘上,以便下次可以再将它恢复到内存的虚拟磁盘上。

▪文件存储空间的分配可以采用显式链接分配或其它方法。

▪空闲空间的管理可以选择位示图或其它方法。

如果采用位示图来管理文件存储空间,并采用显式链接分配方式,可以将位示图合并到FAT中。

▪文件目录结构采用多级目录结构。

为简单起见,可以不使用索引结点,其中的每个目录项包含文件名、物理地址、文件长度等信息,还可以通过目录项实现对文件读和写的保护。

▪要求提供以下有关的文件操作:✧Format:对文件存储器进行格式化,即按照文件系统的结构对虚拟磁盘空间进行布局,并在其上创建根目录以及用于管理文件存储空间等的数据结构。

✧Mkdir:用于创建子目录。

✧Rmdir:用于删除子目录。

✧Ls:用于显示目录。

✧Cd:用于更改当前目录。

✧Create:用于创建文件。

✧Open:用于打开文件。

✧Close:用于关闭文件。

✧Write:用于写文件。

✧Read:用于读文件。

✧Rm:用于删除文件。

数据结构设计磁盘:整个磁盘为一个char数组,数组中的每一个元素当做是一个扇区,每个扇区可以存储1个字节的信息,簇大小为8字节。

FAT表:存储的是指定编号的簇的下一个簇的编号是什么,因为文件是有可能分散在很多的簇里。

文件和文件夹链表:设计为静态链表,每个文件夹都会有一个子目录列表,存在链表中。

文件和目录表:文件和目录相同对待,信息存放在文件目录表中,为一个数组类型。

以上所有的信息存放在一个fs结构体中,所有的结构都为静态实现,所以需要将文件系统存放到磁盘中的时候只需要将整个结构体以二进制性质存放到文件中或者是将从文件中以二进制形式读取。

主要功能实现:Format:清空文件目录表和fat表以及磁盘数组中的所有内容。

Mkdir:首先创建一个目录表项,初始化之后插入到父目录的子目录表中。

Rmdir:利用递归,递归删除当前目录的所有子目录和当前目录本身。

Ls:打印当前的子目录表中的所有内容。

Cd:利用子目录指针寻找目录。

Create:首先在磁盘中申请相应多的簇,然后将信息写入到簇中。

并且在文件目录表中创建一个文件项,并且插入到父目录的子目录表中。

Open:找到文件并且根据fat表打印簇的内容Rm:通过fat表释放簇空间,并且从父目录的表中删除文件。

源代码FS.h#ifndef __FS_ROLL___#define __FS_ROLL___//包含所需的头文件以及宏定义#include <stdio.h>#include <string.h>#include <stdlib.h>#define DISK_SIZE (480 * 1024) //480KB#define BLOCK_SIZE 8 //簇大小#define BLOCK_CNT (DISK_SIZE / BLOCK_SIZE)#define MAX_NAME_LEN 128 //文件名最大长度#define MAX_FILE_CNT 1024 //最多文件个数typedef unsigned int uint; //簇编号//FAT表结构typedef struct FAT {uint next;} FAT;typedef struct List {uint fid, next, prev;} List;typedef enum { File, Directory, Empty } Type;typedef struct File_Type {Type type;char name[MAX_NAME_LEN];char path[MAX_NAME_LEN << 4];union {uint sublist;uint str_pos;};union {uint parid;uint fsize;};} UFD;typedef struct {char disk[DISK_SIZE];uint fpos, flpos;FAT fat[BLOCK_CNT];UFD ufd[MAX_FILE_CNT];List ulist[MAX_FILE_CNT];} FS;void writeToFile(FS *fs, const char *file_name); //将整个磁盘映像写入文件FS *readFromFile(const char *file_name); //从文件中读取磁盘映像FS *createFileSystem(); //创建磁盘void format(FS *fs); //格式化磁盘uint newSubListNode(FS *fs); //新建一个链表节点uint newUFDNode(FS *fs); //新建一个UFD节点void addNode(FS *fs, uint hid, uint node); //添加节点void makeDIR(FS *fs, uint nowfd, const char *dir_name); //创建目录void Ls(FS *fs, uint nowfd); //显示当前目录下面所有文件void Cd(FS *fs, const char *path, int *nowfd); //进入目录int searchPath(FS *fs, const char *argv); //按照绝对路径查找int searchFile(FS *fs, int nowfd, Type type, const char *name); //在当前目录下面搜索文件void createFile(FS *fs, int nowfd, const char *name, const char *buf, int buf_size); //创建文件uint alloc(FS *fs, uint size); //分配簇uint findNextSpace(FS *fs, int spos); //查找下一个空闲簇void writeToDisk(FS *fs, uint str_pos, char *buf, int buf_size); //将文件内容写入到簇中uint calcAddr(uint blockid); //计算簇位置和扇区位置换算void Cat(FS *fs, int nowfd, const char *file_name); //查看文件void outputBlock(FS *fs, int bid); //输出一个簇中的内容void RmFile(FS *fs, int nowfd, const char *file_name); //删除文件void RmDIR(FS *fs, int nowfd, const char *file_name); //递归删除文件和所有文件夹void clearBlock(FS *fs, uint str_pos); //清空一段连续的簇#endifFS.c#include "FS.h"void clearBlock(FS *fs, uint str_pos) {uint now = fs->fat[str_pos].next, p = str_pos;fs->fat[p].next = -1;for(;now != str_pos; now = p) {p = fs->fat[now].next;fs->fat[now].next = -1;}}void RmFile(FS *fs, int nowfd, const char *file_name) {printf("正在删除文件%s\n", file_name);if(searchFile(fs, nowfd, File, file_name) == -1) {puts("文件不存在");return;}UFD *nowdir = &(fs->ufd[nowfd]), *nowp;int i;for(i = fs->ulist[nowdir->sublist].next; i != nowdir->sublist; i = fs->ulist[i].next) {nowp = &(fs->ufd[fs->ulist[i].fid]);if(nowp->type != File) continue;if(strcmp(nowp->name, file_name) != 0) continue;//删除文件并且清除扇区clearBlock(fs, nowp->str_pos);nowp->type = Empty;fs->ulist[fs->ulist[i].prev].next = fs->ulist[i].next;fs->ulist[fs->ulist[i].next].prev = fs->ulist[i].prev;fs->ulist[i].fid = -1;fs->ulist[i].prev = fs->ulist[i].next = i;break;}}void RmDIR(FS *fs, int nowfd, const char *file_name) {printf("正在删除文件夹%s\n", file_name);int fcid;if((fcid = searchFile(fs, nowfd, Directory, file_name)) == -1) {puts("目录不存在"); return;}//将当前目录从父目录的儿子中删除UFD *nowdir = &(fs->ufd[nowfd]), *nowp;int i;for(i = fs->ulist[nowdir->sublist].next; i != nowdir->sublist; i = fs->ulist[i].next) { nowp = &(fs->ufd[fs->ulist[i].fid]);if(nowp->type != Directory) continue;if(strcmp(nowp->name, file_name) != 0) continue;fs->ulist[fs->ulist[i].prev].next = fs->ulist[i].next;fs->ulist[fs->ulist[i].next].prev = fs->ulist[i].prev;fs->ulist[i].fid = -1;fs->ulist[i].prev = fs->ulist[i].next = i;break;}//删除目录下的所有文件和文件夹while(fs->ulist[fs->ufd[fcid].sublist].next != fs->ufd[fcid].sublist) {int nowid = fs->ulist[fs->ulist[fs->ufd[fcid].sublist].next].fid;if(fs->ufd[nowid].type == File) RmFile(fs, fcid, fs->ufd[nowid].name);else RmDIR(fs, fcid, fs->ufd[nowid].name);}fs->ufd[fcid].type = Empty;fs->ulist[fs->ufd[fcid].sublist].fid = -1;}void outputBlock(FS *fs, int bid) {int i, spos = bid * BLOCK_SIZE;for(i = 0; i < BLOCK_SIZE && fs->disk[spos + i] != 0; i++) {putchar(fs->disk[spos + i]);}}void Cat(FS *fs, int nowfd, const char *file_name) {uint fid;if((fid = searchFile(fs, nowfd, File, file_name)) == -1) {puts("要查看的文件不存在");return;}int now = fs->ufd[fid].str_pos;outputBlock(fs, now);for(now = fs->fat[now].next; now != fs->ufd[fid].str_pos; now = fs->fat[now].next) { outputBlock(fs, now);}puts("");}uint calcAddr(uint blockid) {return blockid * BLOCK_SIZE;}uint findNextSpace(FS *fs, int spos) {spos++;while(fs->fat[spos].next != -1) {spos = (spos + 1) % BLOCK_CNT;}return spos;}uint alloc(FS *fs, uint size) {int nowsize = 0, str_pos = findNextSpace(fs, 0), now = str_pos;fs->fat[now].next = now;nowsize = BLOCK_SIZE;while(nowsize < size) {nowsize += BLOCK_SIZE;fs->fat[now].next = findNextSpace(fs, now);now = fs->fat[now].next;fs->fat[now].next = str_pos;}return (uint)str_pos;}void writeToDisk(FS *fs, uint str_pos, char *buf, int buf_size) {strncpy(&(fs->disk[calcAddr(str_pos)]), buf, BLOCK_SIZE);int now = fs->fat[str_pos].next;while(now != str_pos) {buf += BLOCK_SIZE;strncpy(&(fs->disk[calcAddr(now)]), buf, BLOCK_SIZE);now = fs->fat[now].next;}}void createFile(FS *fs, int nowfd, const char *name, const char *buf, int buf_size) { //判断文件是否存在if(searchFile(fs, nowfd, File, name) != -1) {puts("文件已存在,无法创建");return;}uint newfid = newUFDNode(fs), newflid = newSubListNode(fs);UFD *newNode = &(fs->ufd[newfid]);List *newLNode = &(fs->ulist[newflid]);newLNode->fid = newfid;newNode->type = File;strcpy(newNode->name, name);strcpy(newNode->path, fs->ufd[nowfd].path);strcat(newNode->path, name);newNode->fsize = buf_size;newNode->str_pos = alloc(fs, buf_size);writeToDisk(fs, newNode->str_pos, buf, buf_size);addNode(fs, fs->ufd[nowfd].sublist, newflid);}void writeToFile(FS *fs, const char *file_name) {FILE *fp = fopen(file_name, "wb+");printf("%x\n", fp);fwrite((void *)fs, sizeof(FS), 1, fp);fclose(fp);printf("写入%d字节完成\n", (int)(sizeof(FS)));}FS *readFromFile(const char *file_name) {FILE *fp = fopen(file_name, "rb+");printf("%x\n", fp);FS *fs = (FS *)malloc(sizeof(FS));fread((void *)fs, sizeof(FS), 1, fp);fclose(fp);return fs;}int searchFile(FS *fs, int nowfd, Type type, const char *name) {UFD *nowdir = &(fs->ufd[nowfd]), *nowp;int i;//遍历所有子文件夹for(i = fs->ulist[nowdir->sublist].next; i != nowdir->sublist; i = fs->ulist[i].next) { nowp = &(fs->ufd[fs->ulist[i].fid]);if(nowp->type != type) continue;if(strcmp(nowp->name, name) == 0) return fs->ulist[i].fid;}return -1;}int searchPath(FS *fs, const char *argv) {int i;for(i = 0; i < MAX_FILE_CNT; i++) if(fs->ufd[i].type != Empty) {if(strcmp(argv, fs->ufd[i].path) == 0) {return i;}}return -1;}void Cd(FS *fs, const char *argv, int *nowfd) {UFD *nowdir = &(fs->ufd[*nowfd]), *nowp;//如果是返回上一级目录if(strcmp(argv, "..") == 0) {if(nowdir->parid == -1) {puts("当前目录已经是根目录,不能向上");return;}*nowfd = nowdir->parid;return;}//如果是绝对路径else if(argv[0] == '\\') {int tmp = searchPath(fs, argv);if(tmp == -1) {puts("未找到路径");return;}*nowfd = tmp;return;}else {int i;//遍历所有子文件夹for(i = fs->ulist[nowdir->sublist].next; i != nowdir->sublist; i = fs->ulist[i].next) { nowp = &(fs->ufd[fs->ulist[i].fid]);if(nowp->type == File) continue;if(strcmp(nowp->name, argv) == 0) break;}if(i == nowdir->sublist) {puts("未找到该文件夹");}else {printf("find i = %d\n", i);*nowfd = fs->ulist[i].fid;}}}void addNode(FS *fs, uint hid, uint node) {List *newNode = &(fs->ulist[node]), *h = &(fs->ulist[hid]);newNode->prev = h->prev;newNode->next = hid;fs->ulist[h->prev].next = node;h->prev = node;}void Ls(FS *fs, uint nowfd) {UFD *nowdir = &(fs->ufd[nowfd]), *nowp;int i, cnt = 0;puts("当前目录下的文件和文件夹有:");for(i = fs->ulist[nowdir->sublist].next; i != nowdir->sublist; i = fs->ulist[i].next) { nowp = &(fs->ufd[fs->ulist[i].fid]);printf("%s\t\t\t\t%s\n", nowp->name, nowp->type == File ? "文件" : "文件夹");cnt++;}printf("总计%d个\n", cnt);}void makeDIR(FS *fs, uint nowfd, const char *dir_name) {if(searchFile(fs, nowfd, Directory, dir_name) != -1) {puts("文件夹已存在,不能创建");return;}UFD *nowdir = &(fs->ufd[nowfd]);int newfid = newUFDNode(fs), newflid = newSubListNode(fs);UFD *newdir = &(fs->ufd[newfid]);List *newnode = &(fs->ulist[newflid]);//初始化信息newdir->type = Directory;strcpy(newdir->name, dir_name);strcpy(newdir->path, nowdir->path);strcat(newdir->path, dir_name);strcat(newdir->path, "\\");newdir->parid = nowfd;newnode->fid = newfid;newnode->next = newnode->prev = newflid;int newsubflid = newSubListNode(fs);List *newsubnode = &(fs->ulist[newsubflid]);newsubnode->fid = newfid;newsubnode->next = newsubnode->prev = newsubflid;newdir->sublist = newsubflid;//将新的文件夹添加到父文件夹的列表中addNode(fs, nowdir->sublist, newflid);}FS *createFileSystem() {FS *fs = (FS *)malloc(sizeof(FS));return fs;}uint newSubListNode(FS *fs) {int i = fs->flpos;while(fs->ulist[i].fid != -1) i = (i + 1) % MAX_FILE_CNT;return fs->flpos = i;}uint newUFDNode(FS *fs) {int i = fs->fpos;while(fs->ufd[i].type != Empty) i = (i + 1) % MAX_FILE_CNT;return fs->fpos = i;}void format(FS *fs) {int i;//清空磁盘memset(fs->disk, 0, sizeof(fs->disk));//初始化FATfor(i = 0; i < BLOCK_CNT; i++) fs->fat[i].next = -1;//初始化文件链表for(i = 0; i < MAX_FILE_CNT; i++) {fs->ulist[i] = (List) {-1, i, i};}//初始化UFDfs->fpos = fs->flpos = 0;for(i = 0; i < MAX_FILE_CNT; i++) {fs->ufd[i].type = Empty;}//创建根目录UFD *root = &(fs->ufd[newUFDNode(fs)]);root->name[0] = 0;strcpy(root->path, "\\");root->type = Directory;root->parid = -1;uint g = root->sublist = newSubListNode(fs);fs->ulist[g].fid = 0;fs->ulist[g].next = fs->ulist[g].prev = g;}main.c#include <stdio.h>#include <stdlib.h>#include "fs.h"char buf[1024];int main(){char cmd[128], arg[256];FS *fs = createFileSystem();format(fs);int nowfd = 0;while(scanf("%s", cmd) != EOF) {if(strcmp(cmd, "ls") == 0) {Ls(fs, nowfd);}else if(strcmp(cmd, "mkdir") == 0) {scanf("%s", arg);makeDIR(fs, nowfd, arg);}else if(strcmp(cmd, "cd") == 0) {scanf("%s", arg);Cd(fs, arg, &nowfd);}else if(strcmp(cmd, "quit") == 0) {break;}else if(strcmp(cmd, "write") == 0) {writeToFile(fs, "test.img");}else if(strcmp(cmd, "read") == 0) {free(fs);fs = readFromFile("test.img");nowfd = 0;}else if(strcmp(cmd, "create") == 0) {scanf("%s", arg);getchar();printf("请输入文件内容: ");gets(buf);createFile(fs, nowfd, arg, buf, strlen(buf)); }else if(strcmp(cmd, "cat") == 0) {scanf("%s", arg);Cat(fs, nowfd, arg);}else if(strcmp(cmd, "rm") == 0) {scanf("%s", arg);RmFile(fs, nowfd, arg);}else if(strcmp(cmd, "rmdir") == 0) {scanf("%s", arg);RmDIR(fs, nowfd, arg);}else if(strcmp(cmd, "format") == 0) {format(fs);}printf("当前路径: %s\n", fs->ufd[nowfd].path);/*for debugprintf("%d %d\n", fs->fpos, fs->flpos);int i;for(i = 0; i <= fs->flpos; i++) {printf("%d %d %d-->", fs->ulist[i].fid, fs->ulist[i].prev, fs->ulist[i].next);}puts("");printf("nowfd = %d\n", nowfd);*/}//writeToFile(fs, "test.img");return 0;}运行截图Cd,mkdir和ls命令创建和打开文件删除文件夹:。

相关文档
最新文档