【操作系统】C语言编写的FAT16文件系统

这是上学期操作系统的课程设计的
摘要由CSDN通过智能技术生成

这是上学期操作系统的期末课程设计作业之一,主要功能是在物理内存中虚拟出一个1M大小的FAT16的文件系统,然后把它读入内存中,进行具体的文件操作,具体的实用性不大,主要目的是为了练习C语言,帮助理解文件系统的特点,代码如下:

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <time.h>

#define BLOCKSIZE 1024  // 磁盘块大小
#define SIZE 1024000  // 虚拟磁盘空间大小
#define END 65535  // FAT中的文件结束标志
#define FREE 0  // FAT中盘块空闲标志
#define ROOTBLOCKNUM 2  // 根目录区所占盘块数
#define MAXOPENFILE 10  // 最多同时打开文件个数t
#define MAXTEXT 10000

/* 文件控制块 */
typedef struct FCB
{
    char filename[8];  // 文件名
    char exname[3];  // 文件扩展名
    unsigned char attribute;  // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件
    unsigned short time;  // 文件创建时间
    unsigned short date;  // 文件创建日期
    unsigned short first;  // 文件起始盘块号
    unsigned long length;  // 文件长度
    char free;  // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配
}fcb;

/* 文件分配表 */
typedef struct FAT
{
    unsigned short id;  // 磁盘块的状态(空闲的,最后的,下一个)
}fat;
/* 用户打开文件表 */
typedef struct USEROPEN
{
    char filename[8];  // 文件名
    char exname[3];  // 文件扩展名
    unsigned char attribute;  // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件
    unsigned short time;  // 文件创建时间
    unsigned short date;  // 文件创建日期
    unsigned short first;  // 文件起始盘块号
    unsigned long length;  // 文件长度(对数据文件是字节数,对目录文件可以是目录项个数)
    char free;  // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配

	unsigned short dirno;  // 相应打开文件的目录项在父目录文件中的盘块号
    int diroff;  // 相应打开文件的目录项在父目录文件的dirno盘块中的目录项序号
    char dir[80];  // 相应打开文件所在的目录名,这样方便快速检查出指定文件是否已经打开
    int father;  // 父目录在打开文件表项的位置
	int count;  // 读写指针在文件中的位置,文件的总字符数
    char fcbstate;  // 是否修改了文件的FCB的内容,如果修改了置为1,否则为0
	char topenfile;  // 表示该用户打开表项是否为空,若值为0,表示为空,否则表示已被某打开文件占据
}useropen;

/* 引导块 */
typedef struct BLOCK0
{
    char magic[10];  // 文件系统魔数
	char information[200];  // 存储一些描述信息,如磁盘块大小、磁盘块数量、最多打开文件数等
    unsigned short root;  // 根目录文件的起始盘块号
	unsigned char *startblock;  // 虚拟磁盘上数据区开始位置
}block0;
unsigned char *myvhard;  // 指向虚拟磁盘的起始地址
useropen openfilelist[MAXOPENFILE];  // 用户打开文件表数组
int curdir;  // 用户打开文件表中的当前目录所在打开文件表项的位置
char currentdir[80];  // 记录当前目录的目录名(包括目录的路径)
unsigned char* startp;  // 记录虚拟磁盘上数据区开始位置
char myfilename[] = "myfilesys";//文件系统的文件名

void startsys();  // 进入文件系统
void my_format();  // 磁盘格式化
void my_cd(char *dirname);  // 更改当前目录
void my_mkdir(char *dirname);  // 创建子目录
void my_rmdir(char *dirname);  // 删除子目录
void my_ls();  // 显示目录
void my_create (char *filename);  // 创建文件
void my_rm(char *filename);  // 删除文件
int my_open(char *filename);  // 打开文件
int my_close(int fd);  // 关闭文件
int my_write(int fd);  // 写文件
int do_write(int fd, char *text, int len, char wstyle);  // 实际写文件
int my_read (int fd, int len);  // 读文件
int do_read (int fd, int len,char *text);  // 实际读文件
void my_exitsys();  // 退出文件系统
unsigned short findblock();  // 寻找空闲盘块
int findopenfile();  // 寻找空闲文件表项
void startsys()
{
    FILE *fp;
    unsigned char buf[SIZE];
    fcb *root;
	int i;
	myvhard = (unsigned char *)malloc(SIZE);//申请虚拟磁盘空间
	memset(myvhard, 0, SIZE);//将myvhard中前SIZE个字节用 0 替换并返回 myvhard
	if((fp = fopen(myfilename, "r")) != NULL)
	{
	    fread(buf, SIZE, 1, fp);//将二进制文件读取到缓冲区
	    fclose(fp);//关闭打开的文件,缓冲区数据写入文件,释放系统提供文件资源
	    if(strcmp(((block0 *)buf)->magic, "10101010"))//判断开始的8个字节内容是否为文件系统魔数
	    {
	        printf("myfilesys is not exist,begin to creat the file...\n");
	        my_format();
	    }
	    else
	    {
	        for(i = 0; i < SIZE; i++)
                myvhard[i] = buf[i];
	    }
	}
	else
	{
	    printf("myfilesys is not exist,begin to creat the file...\n");
	    my_format();
	}
	root = (fcb *)(myvhard + 5 * BLOCKSIZE);
	strcpy(openfilelist[0].filename, root->filename);
	strcpy(openfilelist[0].exname, root->exname);
	openfilelist[0].attribute = root->attribute;
	openfilelist[0].time = root->time;
	openfilelist[0].date = root->date;
	openfilelist[0].first = root->first;
	openfilelist[0].length = root->length;
	openfilelist[0].free = root->free;
	openfilelist[0].dirno = 5;
	openfilelist[0].diroff = 0;
	strcpy(openfilelist[0].dir, "\\root\\");
	openfilelist[0].father = 0;
	openfilelist[0].count = 0;
	openfilelist[0].fcbstate = 0;
	openfilelist[0].topenfile = 1;
	for(i = 1; i < MAXOPENFILE; i++)
        openfilelist[i].topenfile = 0;
	curdir = 0;
	strcpy(currentdir, "\\root\\");
	startp = ((block0 *)myvhard)->startblock;
}
void my_format()
{
    FILE *fp;
	fat *fat1, *fat2;
	block0 *blk0;
	time_t now;
	struct tm *nowtime;
	fcb *root;
	int i;
	blk0 = (block0 *)myvhard;
	fat1 = (fat *)(myvhard + BLOCKSIZE);
	fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
	root = (fcb *)(myvhard + 5 * BLOCKSIZE);
	strcpy(blk0->magic, "10101010");
	strcpy(blk0->information, "My FileSystem Ver 1.0 \n Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2\n");
	blk0->root = 5;
	blk0->startblock = (unsigned char *)root;
	for(i = 0; i < 5; i++)
    {
        fat1->id = END;
        fat2->id = END;
        fat1++;
        fat2++;
    }
    fat1->id = 6;
    fat2->id = 6;
    fat1++;
    fat2++;
    fat1->id = END;
    fat2->id = END;
    fat1++;
    fat2++;
	for(i = 7; i < SIZE / BLOCKSIZE; i++)
    {
        fat1->id = FREE;
        fat2->id = FREE;
        fat1++;
        fat2++;
    }
    now = time(NULL);
    nowtime = localtime(&now);
    strcpy(root->filename, ".");
    strcpy(root->exname, "");
    root->attribute = 0x28;
    root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
	root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
	root->first = 5;
	root->length = 2 * sizeof(fcb);
	root->free = 1;
	root++;
	now = time(NULL);
    nowtime = localtime(&now);
	strcpy(root->filename, "..");
    strcpy(root->exname, "");
    root->attribute = 0x28;
    root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
	root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
	root->first = 5;
	root->
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值