操作系统 文件存储空间管理

更新时间:2023-05-20 12:10:02 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

操作系统 文件存储空间管理 c++代码

#include "stdio.h"

#include <stdlib.h>

#include <conio.h>

#include <string.h>

int physic[100]; //文件地址缓冲区

int style=1; //文件的类型

char cur_dir[10]="root"; //当前目录

struct command

{

char com[10];

}cmd[13];

struct block

{

int n; //空闲的盘快的个数

int free[50]; //存放空闲盘快的地址

int a; //模拟盘快是否被占用

}memory[20449];

struct block_super

{

int n; //空闲的盘快的个数

int free[50]; //存放进入栈中的空闲块

int stack[50]; //存放下一组空闲盘快的地址

}super_block;

struct node //i结点信息

{

int file_style; //i结点 文件类型

int file_length; //i结点 文件长度

int file_address[100]; //i结点 文件的物理地址

} i_node[640];

struct dir //目录项信息

{

char file_name[10]; //文件名

int i_num; //文件的结点号

char dir_name[10]; //文件所在的目录

} root[640];

void format() //格式化

{

int i,j,k;

super_block.n=50;

for(i=0;i<50;i++) //超级块初始化

{

super_block.free[i]=i; //存放进入栈中的空闲块

操作系统 文件存储空间管理 c++代码

super_block.stack[i]=50+i; //存放下一组的盘块

}

for(i=0;i<640;i++) //i结点信息初始化

{

for(j=0;j<100;j++)

{

i_node[i].file_address[j]=-1;//文件地址

}

i_node[i].file_length=-1; //文件长度

i_node[i].file_style=-1; //文件类型

}

for(i=0;i<640;i++) //根目录区信息初始化

{

strcpy(root[i].file_name,"");

root[i].i_num=-1;

strcpy(root[i].dir_name,"");

}

for(i=0;i<20449;i++) //存储空间初始化

{

memory[i].n=0; //必须有这个

memory[i].a=0;

for(j=0;j<50;j++)

{

memory[i].free[j]=-1;

}

}

for(i=0;i<20449;i++) //将空闲块的信息用成组链接的方法写进每组的最后一个块中 { //存储空间初始化

if((i+1)%50==0)

{

k=i+1;

for(j=0;j<50;j++)

{

if(k<20450)

{

memory[i].free[j]=k;//下一组空闲地址

memory[i].n++; //下一组空闲个数 注意在memory[i].n++之前要给其赋初值 k++;

}

else

{

memory[i].free[j]=-1;

}

操作系统 文件存储空间管理 c++代码

memory[i].a=0; //标记为没有使用

continue; //处理完用于存储下一组盘块信息的特殊盘块后,跳过本次循环 }

for(j=0;j<50;j++)

{

memory[i].free[j]=-1;

}

memory[i].n=0;

}

printf("已经初始化完毕\n");

printf("进入UNIX文件模拟............\n\n");}

void write_file(FILE *fp) //将信息读入系统文件中

{

int i;

fp=fopen("system","wb");

for(i=0;i<20449;i++)

{

fwrite(&memory[i],sizeof(struct block),1,fp);

}

fwrite(&super_block,sizeof(struct block_super),1,fp);

for(i=0;i<640;i++)

{

fwrite(&i_node[i],sizeof(struct node),1,fp);

}

for(i=0;i<640;i++)

{

fwrite(&root[i],sizeof(struct dir),1,fp);

}

fclose(fp);

}

void read_file(FILE *fp) //读出系统文件的信息

{

int i;

fp=fopen("system","rb");

for(i=0;i<20449;i++)

{

fread(&memory[i],sizeof(struct block),1,fp);

}

fread(&super_block,sizeof(struct block_super),1,fp);

for(i=0;i<640;i++)

{

fread(&i_node[i],sizeof(struct node),1,fp);

操作系统 文件存储空间管理 c++代码

for(i=0;i<640;i++)

{

fread(&root[i],sizeof(struct dir),1,fp);

}

fclose(fp);

}

void callback(int length) //回收磁盘空间

{

int i,j,k,m,q=0;

for(i=length-1;i>=0;i--)

{

k=physic[i]; //需要提供要回收的文件的地址

m=49-super_block.n; //回收到栈中的哪个位置

if(super_block.n==50) //注意 当super_block.n==50时 m=-1;的值

{ //super_block.n==50的时候栈满了,要将这个栈中的所有地址信息写进下一个地址中

for(j=0;j<50;j++)

{

memory[k].free[j]=super_block.free[j];

}

super_block.n=0;

memory[k].n=50;

}

memory[k].a=0;

if(m==-1)

{

m=49; //将下一个文件地址中的盘块号回收到栈底中,这个地址中存放着刚才满栈的地址的信息

}

super_block.free[m]=physic[i]; //将下一个文件地址中的盘块号回收到栈中

super_block.n++;

}

}

void allot(int length) //分配空间

{

int i,j,k,m,p;

for(i=0;i<length;i++)

{

k=50-super_block.n; //超级块中表示空闲块的指针

m=super_block.free[k]; //栈中的相应盘块的地址

p=super_block.free[49]; //栈中的最后一个盘块指向的地址

if(m==-1||memory[p].a==1) //检测是否还有下一组盘块

{

操作系统 文件存储空间管理 c++代码

printf("内存不足,不能够分配空间\n");

callback(length);

break;

}

if(super_block.n==1)

{

memory[m].a=1; //将最后一个盘块分配掉

physic[i]=m;

super_block.n=0;

for(j=0;j<memory[m].n;j++) //从最后一个盘块中取出下一组盘块号写入栈中

{

super_block.free[j]=memory[m].free[j];

super_block.n++;

}

continue; //要跳过这次循环,下面的语句在IF中已经执行过

}

physic[i]=m; //栈中的相应盘块的地址写进 文件地址缓冲区

memory[m].a=1;

super_block.n--;

}

}

void create_file(char filename[],int length) //创建文件

{

int i,j;

for(i=0;i<640;i++)

{

if(strcmp(filename,root[i].file_name)==0)

{

printf("文件已经存在,不允许建立重名的文件\n");

return;

}

}

for(i=0;i<640;i++)

{

if(root[i].i_num==-1)

{

root[i].i_num=i;

strcpy(root[i].file_name,filename);

strcpy(root[i].dir_name,cur_dir); //把当前目录名 给新建立的文件

i_node[i].file_style=style;

i_node[i].file_length=length;

allot(length);

for(j=0;j<length;j++)

{

操作系统 文件存储空间管理 c++代码

i_node[i].file_address[j]=physic[j];

}

break;

}

}

}

void create_dir(char filename[]) //创建目录

{

style=0; //0代表文件类型是目录文件

create_file(filename,4);

style=1; //用完恢复初值,因为全局变量,否则

}

void del_file(char filename[]) //删除文件

{

int i,j,k;

for(i=0;i<640;i++)

{

if(strcmp(filename,root[i].file_name)==0)

{

k=root[i].i_num;

for(j=0;j<i_node[k].file_length;j++)

{

physic[j]=i_node[k].file_address[j];

}

callback(i_node[k].file_length); //调用 回收函数

for(j=0;j<100;j++) //删除文件后要将文件属性和目录项的各个值恢复初值 {

i_node[k].file_address[j]=-1; //地址恢复初值

}

strcpy(root[i].file_name,""); //文件名恢复初值

root[i].i_num=-1; //目录项的I结点信息恢复初值

strcpy(root[i].dir_name,""); //目录项的文件目录信息恢复初值

i_node[k].file_length=-1; //文件长度恢复

i_node[k].file_style=-1; //文件类型恢复初值

break;

}

}

if(i==640)

{

printf("不存在这个文件\n");

}

操作系统 文件存储空间管理 c++代码

}

void del_dir(char filename[]) //删除目录 需要判断目录下时候为空,不为空就不删除 {

int i,j,k;

for(i=0;i<640;i++) //还要加条件判断要删除的目录是不是当前目录

{

k=root[i].i_num; //找到目录名字

if( strcmp(root[i].file_name,filename)==0 && strcmp(cur_dir,filename)!=0 && (i_node[k].file_style)==0 )

{

for(j=0;j<640;j++)

{

if(strcmp(filename,root[j].dir_name)==0)

{

printf("目录不为空不能直接删除\n");

break;

}

}

if(j==640)

{

del_file(filename);

break;

}

break;

}

}

if(i==640)

{

printf("这个不是目录文件 或者不存在这个目录,或者你要删除的是当前目录\n"); }

}

void display_curdir() //显示当前目录下的文件列表

{

int i,k;

printf("\t\t文件名字 文件类型 文件长度 所属目录\n");

for(i=0;i<640;i++)

{

if(strcmp(cur_dir,root[i].dir_name)==0) //查询文件中 所在目录信息和当前目录信息相同的数据

{

k=root[i].i_num;

操作系统 文件存储空间管理 c++代码

printf("\t\t %s\t",root[i].file_name); //文件名

printf("\t%d\t",i_node[k].file_style); //文件的类型

printf("%d\t",i_node[k].file_length); //文件的长度

printf("%s\n",root[i].dir_name); //文件所在的目录

}

}

}

void display_dir(char filename[]) //进入指定的目录

{

int i,k;

for(i=0;i<640;i++)

{

k=root[i].i_num; //判断文件类型是不是目录类型

if((strcmp(filename,root[i].file_name)==0) && (i_node[k].file_style==0))

{

strcpy(cur_dir,filename); //将要进入的指定目录设置为当前目录

strcpy(目的,源)

break;

}

}

if(i==640)

{

printf("没有这个目录\n");

}

}

void open_file(char filename[]) //打开文件

{

int i,j,k;

printf("\t\t文件名字 文件类型 文件长度 所属目录\n");

for(i=0;i<640;i++)

{

k=root[i].i_num;

if(strcmp(filename,root[i].file_name)==0 && (i_node[k].file_style==1))

{

printf("\t\t %s\t",root[i].file_name); //文件名

printf("\t%d\t",i_node[k].file_style); //文件的类型

printf("%d\t",i_node[k].file_length); //文件的长度

printf("%s\n",root[i].dir_name); //文件所在的目录

printf("\t\t文件占用的物理地址\n");

for(j=0;j<i_node[k].file_length;j++) //显示物理地址

{

printf("%d ",i_node[k].file_address[j]); //文件具体占用的盘块号

}

printf("\n"); 赋值不要反了

操作系统 文件存储空间管理 c++代码

break;

}

}

if(i==640)

{

printf("没有这个文件 或者这个文件不是正规文件\n");

}

}

void back_dir() //返回上一级目录

{

int i,k;

for(i=0;i<640;i++) //查询和当前目录名相同的目录文件名

{

k=root[i].i_num;

if(strcmp(cur_dir,root[i].file_name)==0 && (i_node[k].file_style==0))

{

strcpy(cur_dir,root[i].dir_name); //将查询到的目录文件名 所在的目录赋值给当前目录 }

}

}

void display_sys() //显示系统信息(磁盘使用情况)

{

int i,m,k=0;

for(i=0;i<20449;i++)

{

if(memory[i].a==0)

k++;

}

m=20449-k;

printf("空闲的盘块数是:\t");

printf("%d\n",k);

printf("使用的盘块数是:\t");

printf("%d\n",m);

}

void help() //显示帮助信息

{printf("以下是文件管理已分配盘块-------------------------------!\n");

printf("注意:创建的文件长度 < 100-----------------------------!\n"); //说明文件

printf("1.初始化-----------------------------------------format!\n");

printf("2.查看当前目录文件列表------------------------------dir!\n");

printf("3.查看文件--------------cat-----(cat + 空格 + 文件名) !\n");

printf("4.查看系统信息-----------------------------------ls !\n");

printf("5.创建目录--------------md------(md + 空格 + 目录名) !\n");

操作系统 文件存储空间管理 c++代码

printf("6.创建文件---vi------(vi + 空格 + 文件名 + 文件长度) !\n");

printf("7.删除文件---------------del-----(del + 空格 + 文件名) !\n");

printf("8.删除目录----------------deldir--(del + 空格 + 目录名)!\n");

printf("9.进入当前目录下的指定目录-----cd--(cd + 空格 + 目录名)!\n");

printf("10.返回上一级目录--------------------------------cd.. !\n");

printf("11.显示帮助命令----------------------------------help !\n");

printf("12.退出文件模拟----------------------------------quit !\n");

printf("13,进入成组链接-----------------------------chengzu !\n");

}

int MA[4]; /*空闲块数组*/

int A[9][4]={{3,1,2,3},{3,4,5,6},{0,0,0,0},{0,0,0,0},{3,0,7,8},

{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; /*磁盘空间*/

int mark[9]; /*存放已分配的块*/

int No=0; /*已分配的块数*/

void display1()

{ int i,j,temp,count;

No=0;

if(MA[1]!=0)

{ i=MA[0];

printf("\ngroup1:");

for(j=1;j<=i;j++)

{ printf("%d ",MA[j]);

mark[++No]=MA[j];

}

temp=MA[1];

count=2;

while(A[temp][1]!=0)

{ printf("\ngroup%d:",count);

i=A[temp][0];

for(j=1;j<=i;j++)

{ printf("%d ",A[temp][j]);

mark[++No]=A[temp][j];

}

count++;

temp=A[temp][1];

}

printf("\ngroup%d:",count);

i=A[temp][0];

for(j=2;j<=i+1;j++)

if(A[temp][j]>0)

{ printf("%d ",A[temp][j]);

mark[++No]=A[temp][j];

操作系统 文件存储空间管理 c++代码

}

}

else

{ i=MA[0];

if(i==1)

printf("\nThe blocks are all assigned");

else

{ printf("\ngroup1:");

for(j=2;j<=i;j++)

{ printf("%d ",MA[j]);

mark[++No]=MA[j];

}

}

}

}

void display() /*显示分组情况*/

{ int i,j;

if(MA[0]!=0)

display1();

else

{ i=MA[1];

for(j=0;j<=3;j++)

MA[j]=A[i][j];

display1();

}

}

void assign() /*分配空闲块*/

{ int s,i;

if(MA[0]>1) /*若该组不止一个空闲块*/

{ i=MA[0];

s=MA[i];

MA[0]--;

printf("\nnumber of the block:%d",s);

}

else if(MA[0]==1) /*只剩一个空闲块*/

{ if(MA[1]!=0) /*还有其它空闲块组*/

{ s=MA[1];

for(i=0;i<=3;i++)

A[0][i]=A[s][i];

MA[0]--;

printf("\nnumber of the block:%d",s);

操作系统 文件存储空间管理 c++代码

}

else /*没有其它空闲块组*/

{ printf("\nThere isn't any space");

return;

}

}

else /*当前组已分配完*/

{ for(i=0;i<=3;i++)

MA[i]=A[0][i];

assign();

}

display(); /*显示分组情况*/

}

void callback() /*回收空闲块*/

{ int i,j,temp;

printf("\ninput the No. of the block you want to callback:");

scanf("%d",&j);

getchar(); /*得到待回收的空闲块号*/

for(temp=1;temp<=No;temp++)

{ if(mark[temp]==j)

break;

}

if(temp<No+1) /*若该空闲块已在,退出*/

{ printf("\nThe block is in the disk");

return;

}

if(MA[0]<3) /*当前组不满3块*/

{ i=MA[0];

MA[i+1]=j;

MA[0]++;

}

else /*已有3块*/

{ for(i=0;i<=3;i++)

A[j][i]=MA[i];

MA[0]=1;

MA[1]=j;

}

display(); /*显示*/

}

int filecontrol();

void menu() /*功能选择函数*/

操作系统 文件存储空间管理 c++代码

{ int choice;

char judge;

printf("文件管理空间管理\n");

printf("\ninput your choice:(1--assign,2--callback,3--backtofilecontrol):\n");

scanf("%d",&choice);

getchar();

if(choice==1)

assign();

else if(choice==2)

callback();

else if(choice==3)

filecontrol();

else

printf("\ninvalid command!");

printf("\ncontinue or not?(y--Yes,n--Not):");

scanf("%c",&judge);

getchar();

if(judge=='y')

menu();

else

{ printf("\nNow the graph is:");

display();

printf("\npress any key to quit");

getchar();

}

}

void chengzulink()

{ int i;

for(i=0;i<=3;i++)

MA[i]=A[0][i];

display();

menu();

}

int filecontrol() //主函数

{ int i, j=0,p,len=0;

char tmp[10],com[10],tmp1[10],k;

struct command tmp2[10];

FILE *fp;

help();

strcpy(cmd[0].com,"format"); //将各个命令存进命令表

strcpy(cmd[1].com,"dir");

strcpy(cmd[2].com,"cat");

strcpy(cmd[3].com,"ls");

strcpy(cmd[4].com,"md");

操作系统 文件存储空间管理 c++代码

strcpy(cmd[5].com,"vi");

strcpy(cmd[6].com,"del");

strcpy(cmd[7].com,"deldir");

strcpy(cmd[8].com,"cd");

strcpy(cmd[9].com,"cd..");

strcpy(cmd[10].com,"help");

strcpy(cmd[11].com,"quit");

strcpy(cmd[12].com,"chengzu");

if((fp=fopen("system","rb"))==NULL) //判断系统文件是否存在

{

printf("can not open file\n");

printf("format the disk Y / N \n");

scanf("%c",&k);

if(k=='y')

format();

}

else

{

read_file(fp); //读取系统文件的内容

}

while(1)

{

j=0; //必须重新给恢复0否则出错

strcpy(tmp,cur_dir);

while(strcmp(tmp,"root")!=0)

{

for(i=0;i<640;i++)

{

p=root[i].i_num;

if(strcmp(tmp,root[i].file_name)==0 && (i_node[p].file_style==0))

{

strcpy(tmp2[j].com,tmp);

j++;

strcpy(tmp,root[i].dir_name);

}

}

}

strcpy(tmp2[j].com,tmp);

for(i=j;i>=0;i--)

{

printf("%s/",tmp2[i].com);

}

操作系统 文件存储空间管理 c++代码

scanf("%s",com); //输入命令并且查找命令的相关操作

for(i=0;i<13;i++)

{

if(strcmp(com,cmd[i].com)==0)

{

p=i;

break;

}

}

if(i==13) //如果没有这个语句以后输入的命令都和第一次输入的效果一样 {

p=14; //随便的一个值

}

switch(p)

{

case 0: format(); //初始化

break;

case 1: display_curdir(); //查看当前目录下的文件列表

break;

case 2: scanf("%s",tmp); //查看文件

open_file(tmp);

break;

case 3: display_sys(); //查看系统信息

break;

case 4:scanf("%s",tmp); //创建目录

create_dir(tmp);

break;

case 5: scanf("%s",tmp); //创建文件

scanf("%d",&len);

create_file(tmp,len);

break;

case 6: scanf("%s",tmp); //删除文件

for(i=0;i<640;i++) //判断文件是不是正规文件

{

j=root[i].i_num;

if(strcmp(tmp,root[i].file_name)==0 && (i_node[j].file_style)==1)

{

del_file(tmp);

break;

}

}

if(i==640)

{

printf("这个不是正规文件文件\n");

操作系统 文件存储空间管理 c++代码

}

break;

case 7:

scanf("%s",tmp); //删除目录

del_dir(tmp);

break;

case 8: scanf("%s",tmp1); //进入当前目录下的指定目录 相当于进入目录 cd + 目录名

display_dir(tmp1);

break;

case 9: back_dir(); //返回上一级目录

break;

case 10:help();

break;

case 11:write_file(fp); //将磁盘利用信息写进系统文件,退出

return 0;

case 12:

chengzulink();

break;

default:printf("SORRY,没有这个命令\n");

break;

}

}

}

int main()

{ int i;

printf("操作系统课程设计\n");

printf("请输入选择\n");

printf("input your choice(1 stand for file control\n 2 stand for chnegzu control)\n"); scanf("%d",&i);

if(i==1)

filecontrol();

else if(i==2)

chengzulink();

else ;

return 0;

}

本文来源:https://www.bwwdw.com/article/fre4.html

Top