为linux系统设计一个简单的二级文件系统。要求做到以下几点:

为linux系统设计一个简单的二级文件系统。要求做到以下几点:,第1张

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#define MEM_D_SIZE 1024*1024//总磁盘空间为1M

#define DISKSIZE 1024 //磁盘块的大小1K

#define DISK_NUM 1024 //磁盘块数目1K

#define FATSIZE DISK_NUM*sizeof(struct fatitem) //FAT表大小

#define ROOT_DISK_NO FATSIZE/DISKSIZE+1 //根目录起始盘块号

#define ROOT_DISK_SIZE sizeof(struct direct) //根目录大小

#define DIR_MAXSIZE 1024 //路径最大长度为1KB

#define MSD 5 //最大子目录数5

#define MOFN 5 //最大文件深度为5

#define MAX_WRITE 1024*128 //最大写入文字长度128KB

struct fatitem /* size 8*/

{

int item /*存放文件下一个磁盘的指针*/

char em_disk/*磁盘块是否空闲标志位 0 空闲*/

}

struct direct

{

/*-----文件控制快信息-----*/

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

{

struct openttableitem

{

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()

}

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=1i<ROOT_DISK_NO-1i++) /*存放 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+1i<DISK_NUMi++)

{

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

if((fp = fopen("disk.dat","wb"))==NULL)

{

printf("Error:\n Cannot open file \n")

return

}

for(i=2i<MSD+2i++) /*-子目录初始化为空-*/

{

root->directitem[i].sign = 0

root->directitem[i].firstdisk = -1

strcpy(root->directitem[i].name,"")

root->directitem[i].next = -1

root->directitem[i].property = '0'

root->directitem[i].size = 0

}

if((fp = fopen("disk.dat","wb"))==NULL)

{

printf("Error:\n Cannot open file \n")

return

}

if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1) /*把虚拟磁盘空间保存到磁盘文件中*/

{

printf("Error:\n File write error! \n")

}

fclose(fp)

}

void enter()

{

FILE *fp

int i

fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char))/*申请 1M空间*/

if((fp=fopen("disk.dat","rb"))==NULL)

{

printf("Error:\nCannot open file\n")

return

}

if(!fread(fdisk,MEM_D_SIZE,1,fp)) /*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/

{

printf("Error:\nCannot read file\n")

exit(0)

}

fat = (struct fatitem *)(fdisk+DISKSIZE) /*找到FAT表地址*/

root = (struct direct *)(fdisk+DISKSIZE+FATSIZE)/*找到根目录地址*/

fclose(fp)

/*--------------初始化用户打开表------------------*/

for(i=0i<MOFNi++)

{

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_MAXSIZE*sizeof(char))

strcpy(bufferdir,"Root:")

}

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)

return

}

int create(char *name)

{

int i,j

if(strlen(name)>8) /*文件名大于 8位*/

return(-1)

for(j=2j<MSD+2j++) /*检查创建文件是否与已存在的文件重名*/

{

if(!strcmp(cur_dir->directitem[j].name,name))

break

}

if(j<MSD+2) /*文件已经存在*/

return(-4)

for(i=2i<MSD+2i++) /*找到第一个空闲子目录*/

{

if(cur_dir->directitem[i].firstdisk==-1)

break

}

if(i>=MSD+2) /*无空目录项*/

return(-2)

if(u_opentable.cur_size>=MOFN) /*打开文件太多*/

return(-3)

for(j=ROOT_DISK_NO+1j<DISK_NUMj++) /*找到空闲盘块 j 后退出*/

{

if(fat[j].em_disk=='0')

break

}

if(j>=DISK_NUM)

return(-5)

fat[j].em_disk = '1' /*将空闲块置为已经分配*/

/*-----------填写目录项-----------------*/

strcpy(cur_dir->directitem[i].name,name)

cur_dir->directitem[i].firstdisk = j

cur_dir->directitem[i].size = 0

cur_dir->directitem[i].next = j

cur_dir->directitem[i].property = '0'

/*---------------------------------*/

fd = open(name)

return 0

}

int open(char *name)

{

int i, j

for(i=2i<MSD+2i++) /*文件是否存在*/

{

if(!strcmp(cur_dir->directitem[i].name,name))

break

}

if(i>=MSD+2)

return(-1)

/*--------是文件还是目录-----------------------*/

if(cur_dir->directitem[i].property=='1')

return(-4)

/*--------文件是否打开-----------------------*/

for(j=0j<MOFNj++)

{

if(!strcmp(u_opentable.openitem[j].name,name))

break

}

if(j<MOFN) /*文件已经打开*/

return(-2)

if(u_opentable.cur_size>=MOFN) /*文件打开太多*/

return(-3)

/*--------查找一个空闲用户打开表项-----------------------*/

for(j=0j<MOFNj++)

{

if(u_opentable.openitem[j].firstdisk==-1)

break

}

/*--------------填写表项的相关信息------------------------*/

u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk

strcpy(u_opentable.openitem[j].name,name)

u_opentable.openitem[j].size = cur_dir->directitem[i].size

u_opentable.cur_size++

/*----------返回用户打开表表项的序号--------------------------*/

return(j)

}

int close(char *name)

{

int i

for(i=0i<MOFNi++)

{

if(!strcmp(u_opentable.openitem[i].name,name))

break

}

if(i>=MOFN)

return(-1)

/*-----------清空该文件的用户打开表项的内容---------------------*/

strcpy(u_opentable.openitem[i].name,"")

u_opentable.openitem[i].firstdisk = -1

u_opentable.openitem[i].size = 0

u_opentable.cur_size--

return 0

}

int write(int fd, char *buf, int len)

{

char *first

int item, i, j, k

int ilen1, ilen2, modlen, temp

/*----------用 $ 字符作为空格 # 字符作为换行符-----------------------*/

char Space = 32

char Endter= '\n'

for(i=0i<leni++)

{

if(buf[i] == '$')

buf[i] = Space

else if(buf[i] == '#')

buf[i] = Endter

}

/*----------读取用户打开表对应表项第一个盘块号-----------------------*/

item = u_opentable.openitem[fd].firstdisk

/*-------------找到当前目录所对应表项的序号-------------------------*/

for(i=2i<MSD+2i++)

{

if(cur_dir->directitem[i].firstdisk==item)

break

}

temp = i/*-存放当前目录项的下标-*/

/*------找到的item 是该文件的最后一块磁盘块-------------------*/

while(fat[item].item!=-1)

{

item =fat[item].item/*-查找该文件的下一盘块--*/

}

/*-----计算出该文件的最末地址-------*/

first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE

/*-----如果最后磁盘块剩余的大小大于要写入的文件的大小-------*/

if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len)

{

strcpy(first,buf)

u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len

cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len

}

else

{

for(i=0i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)i++)

{/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/

first[i] = buf [i]

}

/*-----计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储-------*/

ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)

ilen2 = ilen1/DISKSIZE

modlen = ilen1%DISKSIZE

if(modlen>0)

ilen2 = ilen2+1/*--还需要多少块磁盘块-*/

for(j=0j<ilen2j++)

{

for(i=ROOT_DISK_NO+1i<DISK_NUMi++)/*寻找空闲磁盘块*/

{

if(fat[i].em_disk=='0')

break

}

if(i>=DISK_NUM) /*--如果磁盘块已经分配完了-*/

return(-1)

first = fdisk+i*DISKSIZE/*--找到的那块空闲磁盘块的起始地址-*/

if(j==ilen2-1) /*--如果是最后要分配的一块-*/

{

for(k=0k<len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)-j*DISKSIZEk++)

first[k] = buf[k]

}

else/*-如果不是要最后分配的一块--*/

{

for(k=0k<DISKSIZEk++)

first[k] =buf[k]

}

fat[item].item = i /*--找到一块后将它的序号存放在上一块的指针中-*/

fat[i].em_disk = '1'/*--置找到的磁盘快的空闲标志位为已分配-*/

fat[i].item = -1 /*--它的指针为 -1 (即没有下一块)-*/

}

/*--修改长度-*/

u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len

cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len

}

return 0

}

int read(int fd, char *buf)

{

int len = u_opentable.openitem[fd].size

char *first

int i, j, item

int ilen1, modlen

item = u_opentable.openitem[fd].firstdisk

ilen1 = len/DISKSIZE

modlen = len%DISKSIZE

if(modlen!=0)

ilen1 = ilen1+1/*--计算文件所占磁盘的块数-*/

first = fdisk+item*DISKSIZE/*--计算文件的起始位置-*/

for(i=0i<ilen1i++)

{

if(i==ilen1-1) /*--如果在最后一个磁盘块-*/

{

for(j=0j<len-i*DISKSIZEj++)

buf[i*DISKSIZE+j] = first[j]

}

else /*--不在最后一块磁盘块-*/

{

for(j=0j<len-i*DISKSIZEj++)

buf[i*DISKSIZE+j] = first[j]

item = fat[item].item/*-查找下一盘块-*/

first = fdisk+item*DISKSIZE

}

}

return 0

}

int del(char *name)

{

int i,cur_item,item,temp

for(i=2i<MSD+2i++) /*--查找要删除文件是否在当前目录中-*/

{

if(!strcmp(cur_dir->directitem[i].name,name))

break

}

说通俗一点就类似于数组加上链表的结构,i_addr[8]数组中每一个元素都指向了一个磁盘块,如果那个磁盘块中也存放了一个i_addr[8]数组,并且那个数组中的每个元素也指向了一个磁盘块,那么这就是二级的索引文件结构了~

建议看一下 *** 作系统原理(庞丽萍)一书中的文件系统一章

这个东西是Unix V的一种典型的文件系统~呵呵~

常见的文件系统有FAT、NTFS、ExtFAT、ext2、

ext3,reiserFS、VFAT、APFS。

1、FAT文件系统。

FAT文件系统诞生于1977年,它最初是为软盘设计的文件系统,但是后来随着微软推出dos和win 9×系统,FAT文件系统经过适配被逐渐用到了硬盘上,并且在那时的20年中,一直是主流的文件系统。

2、NTFS文件系统。

它是一种比FAT32功能更加强大的文件系统,从windows.2000后的windows系统的默认件装在NTFS格式的磁盘上。NTFS系统是一个日志性的文件系统,系统中对文件的 *** 作都可以被记录下来,当系统崩溃之后,利用日志功能可以修复数据。

3、ExtFAT文件系统。

ExFAT也是微软开发的文件系统,它是专门为闪存盘设计的文件系统,单个文件突破了4G的限制,而且分区的最大容量可达64ZB,建议512T B。ExFAT在windows,Linux以及Mac系统上,

都可以读写,作为U盘或者是移动硬盘的格式还

是比较合适的。

4、ext2文件系统。

ext2是为解决ext文件系统的缺陷而设计的可扩展的、高性能的文件系统,又被称为二级扩展文件系统。它是Linux文件系统中使用最多的类型,

并且在速度和CPU利用率上较为突出。ext2存取文件的性能极好,并可以支持256字节的长文件名,是GNU/Linux系统中标准的文件系统。

文件系统()

NTFS

NIFS

FAT32

exFAT

卷标)

格式化选项①)

5、ext3文件系统。

ext3是ext2文件系统的日志版本,它在ext2文件系统中增加了日志的功能。ext3提供了3种日志模式:日志(journal)、顺序(ordered)和回写

(writeback)。与ext2相比,ext3提供了更好的安全性以及向上向下的兼容性能。

6、reiserFS文件系统。

reiserFS是Linux环境下最稳定的日志文件系统之一,使用快速的平衡二叉树(binary tree)算法来查找磁盘上的自由空间和已有的文件,其搜索速度高于ext2,reiserFS能够像其他大多数文件系统一样,可动态的分配索引节,而无须在文件系统中创建固定的索引节。

7、VFAT文件系统。

VFAT主要用于处理长文件的一种文件名系统,它运行在保护模式下并使用VCACHE进行缓存,并具有和Windows系列文件系统和Linux文件系统兼容的特性。因此VFAT可以作为Windows和Lin ux交换文件的分区。

8、APFS文件系统。

APFS是苹果公司发布的新的文件格式,替代目前所使用的HFS+格式。这一全新文件系统专门针对闪存/SSD进行优化,提供了更强大的加密、写入时复制元数据、空间分享、文件和目录克隆、快照、目录大小快速调整、原子级安全存储基元,以及改进的文件系统底层技术。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/7950411.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-11
下一篇 2023-04-11

发表评论

登录后才能评论

评论列表(0条)

保存