#include "stdio.h"
#include <stdlib.h>
//#include <conio.h>
#include <string.h>
#include"unistd.h" int physic[]; //文件地址缓冲区
int style=; //文件的类型
char cur_dir[]="root"; //当前目录 struct command
{
char com[];
}cmd[]; struct block
{
int n; //空闲的盘快的个数
int free[]; //存放空闲盘快的地址
int a; //模拟盘快是否被占用
}memory[]; struct block_super
{
int n; //空闲的盘快的个数
int free[]; //存放进入栈中的空闲块
int stack[]; //存放下一组空闲盘快的地址
}super_block; struct node //i结点信息
{
int file_style; //i结点 文件类型
int file_length; //i结点 文件长度
int file_address[]; //i结点 文件的物理地址
} i_node[]; struct dir //目录项信息
{
char file_name[]; //文件名
int i_num; //文件的结点号
char dir_name[]; //文件所在的目录
} root[]; void format() //格式化
{
int i,j,k;
super_block.n=;
for(i=;i<;i++) //超级块初始化
{
super_block.free[i]=i; //存放进入栈中的空闲块
super_block.stack[i]=+i; //存放下一组的盘块
} for(i=;i<;i++) //i结点信息初始化
{
for(j=;j<;j++)
{
i_node[i].file_address[j]=-;//文件地址
}
i_node[i].file_length=-; //文件长度
i_node[i].file_style=-; //文件类型
} for(i=;i<;i++) //根目录区信息初始化
{
strcpy(root[i].file_name,"");
root[i].i_num=-;
strcpy(root[i].dir_name,"");
}
for(i=;i<;i++) //存储空间初始化
{
memory[i].n=; //必须有这个
memory[i].a=;
for(j=;j<;j++)
{
memory[i].free[j]=-;
}
}
for(i=;i<;i++) //将空闲块的信息用成组链接的方法写进每组的最后一个块中
{ //存储空间初始化 if((i+)%==)
{
k=i+;
for(j=;j<;j++)
{
if(k<)
{
memory[i].free[j]=k;//下一组空闲地址
memory[i].n++; //下一组空闲个数 注意在memory[i].n++之前要给其赋初值
k++;
}
else
{
memory[i].free[j]=-;
}
}
memory[i].a=; //标记为没有使用
continue; //处理完用于存储下一组盘块信息的特殊盘块后,跳过本次循环
}
for(j=;j<;j++)
{
memory[i].free[j]=-;
}
memory[i].n=;
}
printf("已经初始化完毕\n");
printf("进入linux文件系统模拟............\n");
} void write_file(FILE *fp) //将信息读入系统文件中
{
int i;
fp=fopen("system","wb");
for(i=;i<;i++)
{
fwrite(&memory[i],sizeof(struct block),,fp);
}
fwrite(&super_block,sizeof(struct block_super),,fp); for(i=;i<;i++)
{
fwrite(&i_node[i],sizeof(struct node),,fp);
}
for(i=;i<;i++)
{
fwrite(&root[i],sizeof(struct dir),,fp);
}
fclose(fp);
} void read_file(FILE *fp) //读出系统文件的信息
{
int i;
fp=fopen("system","rb");
for(i=;i<;i++)
{
fread(&memory[i],sizeof(struct block),,fp);
} fread(&super_block,sizeof(struct block_super),,fp); for(i=;i<;i++)
{
fread(&i_node[i],sizeof(struct node),,fp);
} for(i=;i<;i++)
{
fread(&root[i],sizeof(struct dir),,fp);
}
fclose(fp);
} void callback(int length) //回收磁盘空间
{
int i,j,k,m,q=;
for(i=length-;i>=;i--)
{
k=physic[i]; //需要提供要回收的文件的地址
m=-super_block.n; //回收到栈中的哪个位置
if(super_block.n==) //注意 当super_block.n==50时 m=-1;的值
{ //super_block.n==50的时候栈满了,要将这个栈中的所有地址信息写进下一个地址中
for(j=;j<;j++)
{
memory[k].free[j]=super_block.free[j];
}
super_block.n=;
memory[k].n=;
}
memory[k].a=;
if(m==-)
{
m=; //将下一个文件地址中的盘块号回收到栈底中,这个地址中存放着刚才满栈的地址的信息
}
super_block.free[m]=physic[i]; //将下一个文件地址中的盘块号回收到栈中
super_block.n++;
}
} void allot(int length) //分配空间
{
int i,j,k,m,p;
for(i=;i<length;i++)
{
k=-super_block.n; //超级块中表示空闲块的指针
m=super_block.free[k]; //栈中的相应盘块的地址
p=super_block.free[]; //栈中的最后一个盘块指向的地址
if(m==-||memory[p].a==) //检测是否还有下一组盘块
{
printf("内存不足,不能够分配空间\n");
callback(length);
break;
}
if(super_block.n==)
{
memory[m].a=; //将最后一个盘块分配掉
physic[i]=m;
super_block.n=;
for(j=;j<memory[m].n;j++) //从最后一个盘块中取出下一组盘块号写入栈中
{
super_block.free[j]=memory[m].free[j];
super_block.n++;
}
continue; //要跳过这次循环,下面的语句在IF中已经执行过
}
physic[i]=m; //栈中的相应盘块的地址写进 文件地址缓冲区
memory[m].a=;
super_block.n--;
}
} void create_file(char filename[],int length) //创建文件
{
int i,j;
for(i=;i<;i++)
{
if(strcmp(filename,root[i].file_name)==)
{
printf("文件已经存在,不允许建立重名的文件\n");
return;
}
}
for(i=;i<;i++)
{
if(root[i].i_num==-)
{
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=;j<length;j++)
{
i_node[i].file_address[j]=physic[j];
}
break;
}
}
} void create_dir(char filename[]) //创建目录
{
style=; //0代表文件类型是目录文件
create_file(filename,);
style=; //用完恢复初值,因为全局变量,否则
}
void del_file(char filename[]) //删除文件
{
int i,j,k;
for(i=;i<;i++)
{ if(strcmp(filename,root[i].file_name)==)
{
k=root[i].i_num;
for(j=;j<i_node[k].file_length;j++)
{
physic[j]=i_node[k].file_address[j];
}
callback(i_node[k].file_length); //调用 回收函数
for(j=;j<;j++) //删除文件后要将文件属性和目录项的各个值恢复初值
{
i_node[k].file_address[j]=-; //地址恢复初值
}
strcpy(root[i].file_name,""); //文件名恢复初值
root[i].i_num=-; //目录项的I结点信息恢复初值
strcpy(root[i].dir_name,""); //目录项的文件目录信息恢复初值
i_node[k].file_length=-; //文件长度恢复
i_node[k].file_style=-; //文件类型恢复初值
break;
}
}
if(i==)
{
printf("不存在这个文件\n");
}
} void del_dir(char filename[]) //删除目录 需要判断目录下时候为空,不为空就不删除
{
int i,j,k;
for(i=;i<;i++) //还要加条件判断要删除的目录是不是当前目录
{
k=root[i].i_num; //找到目录名字
if( strcmp(root[i].file_name,filename)== && strcmp(cur_dir,filename)!= && (i_node[k].file_style)== )
{ for(j=;j<;j++)
{
if(strcmp(filename,root[j].dir_name)==)
{
printf("目录不为空不能直接删除\n");
break;
}
}
if(j==)
{
del_file(filename);
break;
} break;
}
}
if(i==)
{
printf("这个不是目录文件 或者不存在这个目录,或者你要删除的是当前目录\n");
} }
void display_curdir() //显示当前目录下的文件列表
{
int i,k;
printf("\t\t文件名字 文件类型 文件长度 所属目录\n");
for(i=;i<;i++)
{
if(strcmp(cur_dir,root[i].dir_name)==) //查询文件中 所在目录信息和当前目录信息相同的数据
{
k=root[i].i_num;
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=;i<;i++)
{
k=root[i].i_num; //判断文件类型是不是目录类型
if((strcmp(filename,root[i].file_name)==) && (i_node[k].file_style==))
{
strcpy(cur_dir,filename); //将要进入的指定目录设置为当前目录 赋值不要反了strcpy(目的,源)
break;
}
}
if(i==)
{
printf("没有这个目录\n");
}
}
void open_file(char filename[]) //打开文件
{
int i,j,k;
printf("\t\t文件名字 文件类型 文件长度 所属目录\n");
for(i=;i<;i++)
{
k=root[i].i_num;
if(strcmp(filename,root[i].file_name)== && (i_node[k].file_style==))
{
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=;j<i_node[k].file_length;j++) //显示物理地址
{
printf("%d ",i_node[k].file_address[j]); //文件具体占用的盘块号
}
printf("\n");
break;
}
}
if(i==)
{
printf("没有这个文件 或者这个文件不是正规文件\n");
}
} void back_dir() //返回上一级目录
{
int i,k;
for(i=;i<;i++) //查询和当前目录名相同的目录文件名
{
k=root[i].i_num;
if(strcmp(cur_dir,root[i].file_name)== && (i_node[k].file_style==))
{
strcpy(cur_dir,root[i].dir_name); //将查询到的目录文件名 所在的目录赋值给当前目录
}
}
}
void display_sys() //显示系统信息(磁盘使用情况)
{
int i,m,k=;
for(i=;i<;i++)
{
if(memory[i].a==)
k++;
}
m=-k;
printf("空闲的盘块数是:\t");
printf("%d\n",k);
printf("使用的盘块数是:\t");
printf("%d\n",m);
} void help() //显示帮助信息
{
printf("注意:创建的文件长度 < 100\n\n"); //说明文件
printf("0.初始化-------------------------format\n");
printf("1.查看当前目录文件列表-----------dir\n");
printf("2.创建文件---------------------create-----(create + 空格 + 文件名 + 文件长度) \n");
printf("3.打开文件-----------------------cat-----(cat + 空格 + 文件名) \n");
printf("4.删除文件-----------------------del-----(del + 空格 + 文件名) \n");
printf("5.创建目录-----------------------md------(md + 空格 + 目录名) \n");
printf("6.删除目录-----------------------deldir--(del + 空格 + 目录名)\n");
printf("7.进入当前目录下的指定目录-------cd--------(cd + 空格 + 目录名)\n");
printf("8.返回上一级目录-----------------cd.. \n");
printf("9.查看系统信息-------------------ls \n");
printf("10.显示帮助命令-----------------help \n");
printf("11.退出文件模拟------------------exit \n");
}
void main() //主函数
{
char tmp[],com[],tmp1[],k;
struct command tmp2[];
int i, j=,p,len=;
FILE *fp;
help();
strcpy(cmd[].com,"format"); //将各个命令存进命令表
strcpy(cmd[].com,"dir");
strcpy(cmd[].com,"cat");
strcpy(cmd[].com,"ls");
strcpy(cmd[].com,"md"); strcpy(cmd[].com,"create");
strcpy(cmd[].com,"del");
strcpy(cmd[].com,"deldir");
strcpy(cmd[].com,"cd");
strcpy(cmd[].com,"cd..");
strcpy(cmd[].com,"help");
strcpy(cmd[].com,"exit");
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()
{
j=; //必须重新给恢复0否则出错
strcpy(tmp,cur_dir);
while(strcmp(tmp,"root")!=)
{
for(i=;i<;i++)
{
p=root[i].i_num;
if(strcmp(tmp,root[i].file_name)== && (i_node[p].file_style==))
{
strcpy(tmp2[j].com,tmp);
j++;
strcpy(tmp,root[i].dir_name);
}
}
} strcpy(tmp2[j].com,tmp);
for(i=j;i>=;i--)
{
printf("%s/",tmp2[i].com);
} scanf("%s",com); //输入命令并且查找命令的相关操作
for(i=;i<;i++)
{
if(strcmp(com,cmd[i].com)==)
{
p=i;
break;
}
}
if(i==) //如果没有这个语句以后输入的命令都和第一次输入的效果一样
{
p=; //随便的一个值
}
switch(p)
{
case : format(); //初始化
break;
case : display_curdir(); //查看当前目录下的文件列表
break;
case : scanf("%s",tmp); //查看文件
open_file(tmp);
break;
case : display_sys(); //查看系统信息
break;
case :scanf("%s",tmp); //创建目录
create_dir(tmp);
break;
case : scanf("%s",tmp); //创建文件
scanf("%d",&len);
create_file(tmp,len);
break;
case : scanf("%s",tmp); //删除文件
for(i=;i<;i++) //判断文件是不是正规文件
{
j=root[i].i_num;
if(strcmp(tmp,root[i].file_name)== && (i_node[j].file_style)==)
{
del_file(tmp);
break;
}
}
if(i==)
{
printf("这个不是正规文件文件\n");
}
break;
case :
scanf("%s",tmp); //删除目录
del_dir(tmp);
break;
case : scanf("%s",tmp1); //进入当前目录下的指定目录 相当于进入目录 cd + 目录名
display_dir(tmp1);
break;
case : back_dir(); //返回上一级目录
break;
case :help();
break;
case :write_file(fp); //将磁盘利用信息写进系统文件,退出
return;
default:printf("没有这个命令\n");
break;
}
}
}

linux文件系统模拟的更多相关文章

  1. Linux实战教学笔记08:Linux 文件的属性(上半部分)

    第八节 Linux 文件的属性(上半部分) 标签(空格分隔):Linux实战教学笔记 第1章 Linux中的文件 1.1 文件属性概述(ls -lhi) linux里一切皆文件 Linux系统中的文件 ...

  2. Linux文件查找.md

    Linux 文件查找 在Linux系统的查找相关的命令: which 查看可执行文件的位置 whereis 查看文件的位置 locate 配合数据库查看文件位置 find 实际搜寻硬盘查询文件名称 w ...

  3. Linux 文件压缩与归档

    .note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...

  4. Linux文件类型

    1.windows系统和Linux系统的区别 windows通过问价扩展名来区分文件类型,例如*.txt是一个文本文件, linux系统文件的扩展名和文件类型没有关系 为了容易区分文件类型,linux ...

  5. 修改linux文件权限

    Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权限分为只读,只写和可执行三种.以文件为例,只读权限表示只允许读其内容,而禁 ...

  6. Linux文件和目录权限详细讲解

    转载请标明出处: http://www.cnblogs.com/why168888/p/5965180.html 本文出自:[Edwin博客园] Linux文件和目录权限解读 如何设置Linxu文件和 ...

  7. linux 文件系统结构及命令

    1.linux 文件系统结构 / 根目录 root |--mnt/ | |--sdcard/  挂载点 | |--usb0 | |--cdrom |--home | |--soft01 <- 用 ...

  8. linux 文件权限、类型、命名规则

    文件权限 -rwxr-x--t        文件类型 用户权限 组权限 其他用户权限 umask是一个掩码,设置文件的默认权限,会屏蔽掉不想授予该安全级别的权限,从对象的全权权限中减掉:对文件全权权 ...

  9. linux文件权限查看及修改(实用)

    查看Linux文件的权限:ls -l 文件名称 查看linux文件夹的权限:ls -ld 文件夹名称(所在目录) 修改文件及文件夹权限: sudo chmod -(代表类型)×××(所有者)×××(组 ...

随机推荐

  1. python 线性回归示例

    说明:此文的第一部分参考了这里 用python进行线性回归分析非常方便,有现成的库可以使用比如:numpy.linalog.lstsq例子.scipy.stats.linregress例子.panda ...

  2. [原创]JavaScript继承详解

    原文链接:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html 面向对象与基于对象 几乎每个开发人员都有面向对象语言(比如C++. ...

  3. 深入浅出jsonp

    前言 第一次听说jsonp,其实早在2年之前.当时在做一个活动页面的抽奖模块,要从服务端get一个概率,当时什么都不懂,同事说用ajax,我就用ajax,同事说dataType改成jsonp,我就改成 ...

  4. Scala学习笔记(五):类和对象

    对象实例的变量组成了对象的内存映射 public是Scala的默认访问级别 Scala里方法参数的一个重要特征是它们都是val,不是var Scala不能定义静态成员 单例对象(singleton o ...

  5. zoeDylan.js框架-数据底层

    zoeDylan.js是墨芈自己写的一套前端框架,不过由于墨芈经验不足,所以框架内部代码有些混乱. 墨芈写这套框架的目的是为了存储以后做前端开发过程中的一些代码,简单的说这套框架就是一个大杂烩. 这套 ...

  6. EntityFramework中Mapper怎么定义联合主键?

    HasKey(m => new { m.StoreId, m.CarTypeId, m.CarLevel}) 用“new {}”联合主键以“,”分隔形式定义

  7. Customizing Navigation Bar and Status Bar

    Like many of you, I have been very busy upgrading my apps to make them fit for iOS 7. The latest ver ...

  8. javascript与服务器1

    A. 通过在客户端设置Cookie,然后在服务器端读取它. 关于Cookie只说明一点, 它是存储在客户端机器上的一小块信息, 可以有客户端程序或服务器程序创建,并通过http传递.常用于跟踪用户在客 ...

  9. 小菜鸟学 MQ(三)

    创建程序测试MQ 1,创建生产者 package com.robert; import java.util.Hashtable; import java.util.Map; import javax. ...

  10. 【BZOJ 1013】【JSOI2008】球形空间产生器sphere 高斯消元基础题

    最基础的高斯消元了,然而我把j打成i连WA连跪,考场上再犯这种错误就真的得滚粗了. #include<cmath> #include<cstdio> #include<c ...