/*----------------------------------------------------------------------------------------------*/
/*----------------------------一个单用户文件系统的实现------------------------------------------*/
/*----------------------------------------------------------------------------------------------*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define DIR_LENGTH 1024 /*路径最长可达100字节*/
#define MAX_WRITE 1024*128 /*写入文字可达128k字节*/
#define MEM_D_SIZE 1024*1024 /*1M磁盘空间*/
#define DISKSIZE 1024 /*磁盘快的大小 1K*/
#define MSD 5 /*最大子目录数 5 (类似五叉树)*/
#define DISK_NUM MEM_D_SIZE/DISKSIZE /*磁盘快数目 1024=1M/1K*/
#define FATSIZE DISK_NUM*sizeof(struct fatitem) /*FAT表大小 8K=8192B (理想应该是 1.5K)*/
#define MOFN 5 /*最大文件打开数 5 (即除根以外最大深度为5)*/
#define ROOT_DISK_NO FATSIZE/DISKSIZE+1 /*根目录起始盘快号 9*/
#define ROOT_DISK_SIZE sizeof(struct direct)/*根目录大小 196*/
/*---------------FAT表项结构-----------------------*/
struct fatitem /* size 8*/
{
int item; /*存放文件下一个磁盘的指针*/
char em_disk; /*磁盘块是否空闲标志位 0 空闲*/
};
/*-------------------目录项结构------------------------*/
struct direct /* size 196*/
{
/*-----文件控制快信息-----*/
struct FCB
{
char name[9]; /*文件/目录名 8位*/
char property; /*属性 1位目录 0位普通文件*/
int size; /*文件/目录字节数(原注释位盘块数)*/
int firstdisk; /*文件/目录 起始盘块号*/
int next; /*子目录起始盘块号*/
int sign; /*1是根目录 0不是根目录*/
}directitem[MSD+2];
};
/*------------------文件打开表项结构--------------------------*/
struct opentable /* size 104*/
{
struct openttableitem /* size 20*/
{
char name[9]; /*文件名*/
int firstdisk; /*起始盘块号*/
int size; /*文件的大小*/
}openitem[MOFN];
int cur_size; /*当前打文件的数目*/
};
/*-------------------------------------------------------------------*/
struct fatitem *fat; /*FAT表*/
struct direct *root; /*根目录*/
struct direct *cur_dir; /*当前目录*/
struct opentable u_opentable; /*文件打开表*/
int fd=-1; /*文件打开表的序号*/
char *bufferdir; /*记录当前路径的名称*/
char *fdisk; /*虚拟磁盘起始地址*/
void initfile();
void format();
void enter();
void halt();
int create(char *name);
int open(char *name);
int close(char *name);
int write(int fd,char *buf,int len);
int read(int fd,char *buf);
int del(char *name);
int mkdir(char *name);
int rmdir(char *name);
void dir();
int cd(char *name);
void print();
void show();
/*----------------------------------------------------------------------------------------------*/
/*------------------------------------------初始化文件系统--------------------------------------*/
void initfile()
{
fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/
format();
free(fdisk);
}
/*----------------------------------------------------------------------------------------------*/
/*------------------------------------------格式化----------------------------------------------*/
void format()
{
int i;
FILE *fp;
fat = (struct fatitem *)(fdisk+DISKSIZE); /*计算FAT表地址(为什么向后偏移 1k)*/
/*-----初始化FAT表------------*/
fat[0].item=-1; /*引导块*/
fat[0].em_disk='1';
for(i=1;i<ROOT_DISK_NO-1;i++) /*存放 FAT表的磁盘块号*/
{
fat[i].item=i+1;
fat[i].em_disk='1';
}
fat[ROOT_DISK_NO-1].item=-1;
fat[ROOT_DISK_NO-1].em_disk='1';
fat[ROOT_DISK_NO].item=-1; /*存放根目录的磁盘块号*/
fat[ROOT_DISK_NO].em_disk='1';
for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)
{
fat[i].item = -1;
fat[i].em_disk = '0';
}
/*-----------------------------------------------*/
root = (struct direct *)(fdisk+DISKSIZE+FATSIZE); /*根目录的地址*/
/*初始化目录*/
/*---------指向当前目录的目录项---------*/
root->directitem[0].sign = 1;
root->directitem[0].firstdisk = ROOT_DISK_NO;
strcpy(root->directitem[0].name,".");
root->directitem[0].next = root->directitem[0].firstdisk;
root->directitem[0].property = '1';
root->directitem[0].size = ROOT_DISK_SIZE;
/*-------指向上一级目录的目录项---------*/
root->directitem[1].sign = 1;
root->directitem[1].firstdisk = ROOT_DISK_NO;
strcpy(root->directitem[1].name,"..");
root->directitem[1].next = root->directitem[0].firstdisk;
root->directitem[1].property = '1';
root->directitem[1].size = ROOT_DISK_SIZE;
for(i=2;i<MSD+2;i++) /*-子目录初始化为空-*/
{
root->directitem[i].sign = 0;
root->directitem[i].firstdisk = -1;
strcpy(root->directitem[i].name,"");
root->directitem[i].next = -1;
root->directitem[i].property = '0';
root->directitem[i].size = 0;
}
/*-------测试写入文件的数据---------
for(i=0;i<DISK_NUM;i++)
{
printf("%d,%d\n",fat[i].item,fat[i].em_disk);
}
for(i=0;i<MSD+2;i++)
{
printf("%d,%s,%d,%c,%d,%d\n",root->directitem[i].firstdisk,
root->directitem[i].name,root->directitem[i].next,
root->directitem[i].property,root->directitem[i].sign,
root->directitem[i].size);
}
for(i=0;i<DISK_NUM;i++)
{
fread(&fat[i],sizeof(struct fatitem),1,fp);
printf("%d,%d\n",fat[i].em_disk,fat[i].item);
}
for(i=0;i<MSD+2;i++)
{
fread(&root->directitem[i],sizeof(struct FCB),1,fp);
printf("%d,%s,%d,%c,%d,%d\n",root->directitem[i].firstdisk,
root->directitem[i].name,root->directitem[i].next,
root->directitem[i].property,root->directitem[i].sign,
root->directitem[i].size);
}
------test end-----*/
if((fp = fopen("disk.dat","wb"))==NULL)
{
printf("Error:\n Cannot open file \n");
return;
}
if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1) /*把虚拟磁盘空间保存到磁盘文件中*/
{
printf("Error:\n File write error! \n");
}
fclose(fp);
}
/*----------------------------------------------------------------------------------------------*/
/*--------------------------------进入文件系统--------------------------------------------------*/
void enter()
{
FILE *fp;
int i;
fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/
if((fp=fopen("disk.dat","rb"))==NULL)
{
printf("Error:\nCannot open file\n");
return;
}
if(!fread(fdisk,MEM_D_SIZE,1,fp)) /*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/
{
printf("Error:\nCannot read file\n");
exit(0);
}
fat = (struct fatitem *)(fdisk+DISKSIZE); /*找到FAT表地址*/
root = (struct direct *)(fdisk+DISKSIZE+FATSIZE);/*找到根目录地址*/
fclose(fp);
/*--------------初始化用户打开表------------------*/
for(i=0;i<MOFN;i++)
{
strcpy(u_opentable.openitem[i].name,"");
u_opentable.openitem[i].firstdisk = -1;
u_opentable.openitem[i].size = 0;
}
u_opentable.cur_size = 0;
cur_dir = root; /*当前目录为根目录*/
bufferdir = (char *)malloc(DIR_LENGTH*sizeof(char));
strcpy(bufferdir,"Root:"); /*显示根目录为E:*/
}
/*----------------------------------------------------------------------------------------------*/
/*------------------------------------退出文件系统----------------------------------------------*/
void halt()
{
FILE *fp;
int i;
if((fp=fopen("disk.dat","wb"))==NULL)
{
printf("Error:\nCannot open file\n");
return;
}
if(!fwrite(fdisk,MEM_D_SIZE,1,fp)) /*把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */
{
printf("Error:\nFile write error!\n");
}
fclose(fp);
free(fdisk);
free(bufferdir);
for(i=0;i<MOFN;i++) /*撤销用户打开表 (好像没有必要,系统自动会回收)*/
{
strcpy(u_opentable.openitem[i].name,"");
u_opentable.openitem[i].firstdisk = 0;
u_opentable.openitem[i].size = 0;
}
u_opentable.cur_size = 0; /*用户打开文件数清零*