昨天心血来潮,一时兴起,居然会想要手撸文件系统,结果撸了十几个小时。

毕竟也是个较真的人,一些细节总想着抠,结果越抠代码越长,好在BUG没有越抠越多。撸玩基础功能还不愿罢休,继续撸界面和一些人性化设计,然后又撸了撸功能。最后代码有一千三百多行,去掉注释还有一千一百多行,看到其他同学只撸了五百多行,宝宝心里委屈。

代码太长了,贴一点意思一下好了。

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

#define	BLOCKSIZE		1024	//磁盘块大小
#define BLOCKNUM		1000	//磁盘块数量
#define	SIZE			1024000	//虚拟磁盘空间大小
#define END         	65534  	//FAT中文件结束标志
#define FREE        	0		//FAT盘中空闲块标志
#define ROOTBLOCKNUM	2		//根目录区所占盘块总数
#define MAXOPENFILE    	10		//最多同时打开文件个数
#define MAXFILEDIR		200		//目录名最大长度
#define MAXFILENAMELEN	16		//文件名最大长度
#define MAXEXNAMELEN	3		//文件扩展名最大长度
#define INFORMATIONLEN	200		//引导块描述信息最大长度
#define FATBLOCKNUM		2		//FAT表块数量 
#define SHOWLOG			1		//是否显示系统操作信息
#define ISDEBUG			1		//是否为调试模式
#define SHOWVAR			1		//是否变量信息
#define MAXBUFLEN		200		//暂存日志字符串最大长度
#define MAXLOGLEN		100000	//系统操作日志最大长度
#define MAXINPUTLEN		1000	//输入命令最大长度
#define MAXTEXTLEN		10000	//暂存字符串最大长度

typedef struct FCB {
	char filename[MAXFILENAMELEN + 1];
	char exname[MAXEXNAMELEN + 1];
	unsigned char attribute;
	unsigned short time;
	unsigned short date;
	unsigned short first;
	unsigned long length;
	char free;
} fcb;

typedef struct FAT {
	unsigned short id;
} fat;

typedef struct USEROPEN {
	char filename[MAXFILENAMELEN + 1];
	char exname[MAXEXNAMELEN + 1];
	unsigned char attribute;
	unsigned short time;
	unsigned short date;
	unsigned short first;
	unsigned long length;
	char free;
	int dirno;
	int diroff;
	char dir[MAXFILEDIR + 1];
	int father;
	int count;
	char fcbstate;
	char topenfile;
} useropen;

typedef struct BLOCK0 {
	char information[INFORMATIONLEN + 1]; 
	unsigned short root;
	unsigned char *startblock;
} block0;

unsigned char *myvhard;					//虚拟磁盘起始地址
useropen openfilelist[MAXOPENFILE]; 	//用户打开文件表数组
int curdirptr;							//当前用户打开文件表的位置
char currentdir[MAXFILEDIR];			//当前目录名
unsigned char *startp;					//虚拟磁盘数据区开始位置
const char *filepath = "sys";           //文件系统文件路径
const char *filebkpath = "sys.bk";      //文件系统备份文件路径
FILE *fp;								//磁盘文件地址
fcb *root;								//根目录
char tmpbuf[MAXBUFLEN];					//暂存字符串 
char logs[MAXLOGLEN];					//日志信息

void debug();
void initwindow();
void showhello();
void showmenu();
void showlog();
void showreload();
void showbye();
void showwrite();
void addlog(const char *fmt, ...);
void adderror(const char *fmt, ...);
void fcb2useropen(useropen *useropen0, fcb *fcb0);
void useropen2fcb(fcb *fcb0, useropen *useropen0);
int findblock();
int findopenfile();
int findopenned();
void do_free(unsigned short blkno);
void showopenfile();
void do_create(fcb *fcb0, char *dirname, unsigned char attribute, unsigned short blkno);
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();

/*
(1)对应命令:无
(2)命令调用格式:无
(3)函数设计格式:void main()
(4)功能:系统主函数
(5)输入:无
(6)输出:无
(7)函数需完成的工作:
① 对前面定义的全局变量进行初始化; 
② 调用startsys()进入文件系统;
③ 列出文件系统提供的各项功能及命令调用格式;
④ 显示命令行提示符,等待用户输入命令;
⑤ 将用户输入的命令保存到一个buf中;
⑥ 对buf中的内容进行命令解析,并调用相应的函数执行用户键入的命令;
⑦ 如果命令不是"my_exitsys",则命令执行完毕后转④。
*/
void main() {
	char inputs[MAXINPUTLEN + 1];
	char *cmd, *para;
	int fd;
	initwindow();
	startsys();
	showhello();
	showmenu();
	do {
		printf("%s ", openfilelist[curdirptr].dir);
		fgets(inputs, MAXINPUTLEN, stdin);
		inputs[strlen(inputs) - 1] = '\0';
		if (strcmp(inputs, "") != 0) {
			cmd = strtok(inputs, " ");
			para = strtok(NULL, " ");
			if (strcmp(cmd, "format") == 0) {
				my_format();
			} else if (strcmp(cmd, "cd") == 0) {
				if (para) my_cd(para);
				else adderror("Please enter the parameter.\n");
			} else if (strcmp(cmd, "mkdir") == 0) {
				if (para) my_mkdir(para);
				else adderror("Please enter the parameter.\n");
			} else if (strcmp(cmd, "rmdir") == 0) {
				if (para) {
					if ((fd = findopenned(para)) == -1)
						if ((fd = my_open(para)) != -1) my_rmdir(para);
				} else adderror("Please enter the parameter.\n");
			} else if (strcmp(cmd, "ls") == 0) {
				my_ls();
			} else if (strcmp(cmd, "create") == 0) {
				if (para) my_create(para);
				else adderror("Please enter the parameter.\n");
			} else if (strcmp(cmd, "rm") == 0) {
				if (para) {
					if ((fd = findopenned(para)) == -1)
						if ((fd = my_open(para)) != -1) my_rm(para);
				} else adderror("Please enter the parameter.\n");
			} else if (strcmp(cmd, "open") == 0) {
				if (para) curdirptr = my_open(para);
				else adderror("Please enter the parameter.\n");
			} else if (strcmp(cmd, "close") == 0) {
				if (para) {
					fd = findopenned(para);
					my_close(fd);
				} my_close(curdirptr);
			} else if (strcmp(cmd, "write") == 0) {
				if (para) {
					if ((fd = findopenned(para)) == -1)
						if ((fd = my_open(para)) != -1) my_write(fd);
				} else my_write(curdirptr);
			} else if (strcmp(cmd, "read") == 0) {
				if (para) {
					if ((fd = findopenned(para)) == -1)
						if ((fd = my_open(para)) != -1) my_read(fd, openfilelist[fd].length);
				} else my_read(curdirptr, openfilelist[curdirptr].length);
			} else if (strcmp(cmd, "disp") == 0) {
				showopenfile();
			} else if (strcmp(cmd, "reload") == 0) {
				my_exitsys();
				sprintf(cmd, "copy %s %s /y", filepath, filebkpath);
				system(cmd);
				showreload();
				break;
			} else if (strcmp(cmd, "cls") == 0) {
				system("cls");
			} else if (strcmp(cmd, "help") == 0) {
				showmenu();
			} else if (strcmp(cmd, "exit") == 0) {
				my_exitsys();
				showbye();
				break;
			} else {
				adderror("Command '%s' isn't found.\n", cmd);
			}
		}
		if (SHOWLOG && !ISDEBUG) showlog();
		if (SHOWVAR) debug();
	} while (1);
	return;
}

void debug() {
	printf("curdirptr: %d\n", curdirptr);
	return;
}

void initwindow() {
	system("@echo off");
	system("title FileSystem Version 1.0");
	system("mode con cols=80 lines=40");
	system("color 79");
	return;
}

void showhello() {
	printf("*******************************************************************************\n");
	printf("*%78c\n", '*');
	printf("*% 20cWelcome to the FileSystem version 1.0% 20c*\n", ' ', ' ');
	printf("*%78c\n", '*');
	printf("*******************************************************************************\n");
	return;
}

void showmenu() {
	printf("*******************************************************************************\n");
	printf("* %-15s: %-59s*\n", "format", "format the virtual disk.");
	printf("* %-15s: %-59s*\n", "cd dirname", "jump to the directory.");
	printf("* %-15s: %-59s*\n", "mkdir dirname", "create a new directory.");
	printf("* %-15s: %-59s*\n", "rmdir dirname", "delete a directory.");
	printf("* %-15s: %-59s*\n", "ls", "show current directory items.");
	printf("* %-15s: %-59s*\n", "create filename", "create a new file.");
	printf("* %-15s: %-59s*\n", "rm filename", "remove a file.");
	printf("* %-15s: %-59s*\n", "open filename", "open a file.");
	printf("* %-15s: %-59s*\n", "close", "close current file.");
	printf("* %-15s: %-59s*\n", "write", "write text into current file.");
	printf("* %-15s: %-59s*\n", "write filename", "write text into file.");
	printf("* %-15s: %-59s*\n", "read", "read current file and display.");
	printf("* %-15s: %-59s*\n", "read filename", "read file and display.");
	printf("* %-15s: %-59s*\n", "disp", "display all openned file.");
	printf("* %-15s: %-59s*\n", "reload", "load system backup file.");
	printf("* %-15s: %-59s*\n", "cls", "clear the screen.");
	printf("* %-15s: %-59s*\n", "help", "display the help menu.");
	printf("* %-15s: %-59s*\n", "exit", "exit the system.");
	printf("*******************************************************************************\n");
	return;
}

void showlog() {
	printf("*******************************************************************************\n");
	printf("*%37cLog%37c*\n", ' ', ' ');
	printf("*******************************************************************************\n");
	printf("%s", logs);
	logs[0] = '\0';
	printf("*******************************************************************************\n");
	return;
}

void showreload() {
	printf("*******************************************************************************\n");
	printf("*%24cFileSystem has loaded backup.%24c*\n", ' ', ' ');
	printf("*%26cPlease reboot FileSystem.%26c*\n", ' ', ' ');
	printf("*******************************************************************************\n");
	return;
}

void showbye() {
	printf("*******************************************************************************\n");
	printf("*%23cThank you for using FileSystem.%23c*\n", ' ', ' ');
	printf("*%33c~ Goodbye ~%33c*\n", ' ', ' ');
	printf("*******************************************************************************\n");
	return;
}

void showwrite() {
	printf("*******************************************************************************\n");
	printf("* %-15s: %-59s*\n", "1", "rewrite.");
	printf("* %-15s: %-59s*\n", "2", "overwrite.");
	printf("* %-15s: %-59s*\n", "3", "insert.");
	printf("*******************************************************************************\n");
	return;
}
转载保留版权:http://haipz.com/blog/i/6527 - 海胖博客