操作系统: 二级目录文件系统部分功能的实现(主要是C语言,未完整实现)

第一次通过csdn到github学习的一个项目,由于时间问题,没有完全实现,对原作者的代码进行了改进
原作者博客:https://blog.csdn.net/nk_test/article/details/50389128
github地址:
https://github.com/Tachone/FileSystem
原作者的代码实现的功能:

void do_Help()
{
	cout << "Login	userName pwd	用户登陆" << endl;
	cout << "Logout	用户登出" << endl;
	cout << "Register usrName pwd   用户注册" << endl;
	cout << "Passwd	oldPwd  newPwd    修改用户口令" << endl;
	cout << "Open   filename mode   打开文件" << endl;
	cout << "Close  filename   关闭文件" << endl;
	cout << "Create	 filename mode	  建立文件" << endl;
	cout << "Delete	 filename   删除文件" << endl;
	cout << "Write	filename buffer nbytes   写文件" << endl;
	cout << "Read 	filename buffer nbytes   读文件" << endl;
	cout << "dir   列出该用户下所有文件" << endl;
	cout << "Chmod	filename mode  	 改变文件权限" << endl;
	cout << "Chown	filename new_owner    改变文件拥有者" << endl;
	cout << "Mv	srcFile desFile	   改变文件名" << endl;
	cout << "Copy   srcFile desFile   文件拷贝" << endl;
	cout << "Type	filename     显示文件内容" << endl;
	cout << "Exit   退出程序" << endl;
	cout << "sysc   同步到磁盘 " << endl;
}

我的代码实现功能:

void Help() {
	printf("欢迎使用由广大菜鸟完成的二级文件目录系统!\n");
	printf("******************************************\n");
	printf("Loin                              用户登陆\n");
	printf("Logout	                          用户登出\n");
	printf("Exit	                          退出系统\n");
	printf("Create 	xx.format  mode           创建文件\n");
	printf("Write  	xx.format                 填写文件\n");
	printf("Delete 	xx.format                 删除文件\n");
	printf("open   	xx.format                 打开文件\n");
	printf("Read   	xx.format   nbytes        查看文件\n");
	printf("ReadAll xx.format                 查看全部\n");
	printf("Close                             关闭文件\n");
	printf("dir                               查看目录\n");
	printf("Register userName userPwd         登记用户\n");
	printf("******************************************\n");
}

1、代码区域:

1.1、 fileSystemStruct.h

#pragma once
#ifndef _FILESYSTEMSTRUCT_H_
#define  _FILESYSTEMSTRUCT_H_
/*
	以一个文本文件disk.txt模拟硬盘,设定硬盘容量分为100个物理块,每个物理块的大小512字节(为了测试方便,最后67个数据块每一个的大小为256字节),盘块之间用(‘\n’)分割。
	因此一个盘块:512字节数据+1字节(‘\n’)分割符=513字节,则disk.txt 长度=51300(100×513)+1字节(文件结束符)=51301字节。
	100块盘块的分布:
	1#: MFD块,存放MFD信息;
	2-17#: UFD块,存放UFD信息;
	18-33#: UOF块,存放UOF信息;
	其余物理块用于存放文件内容(1行1个磁盘)。
*/


// 主文件目录 32B  1#盘块
typedef struct mfd
{
	char usrName[14];
	char usrPwd[14];
	int link;			//该用户的UFD所在的盘号 4B
}MFD;

// 用户文件目录 46B 2-17#盘块
typedef struct ufd
{
	char creator[14];	//创建用户名
	char filename[14];	//文件名14B
	int mode;			// 文件权限0 - readonly;  1 - writeonly;  2 - read / write 3 - private
	int length;			//文件长度(以字节数计算)
	int addr;			//该文件的第1个文件块对应的物理块号
}UFD;

// 用户已打开表:32B 18-33# 盘块
typedef struct uof
{
	char creator[14];	//创建用户名
	char filename[14];
	int mode;			//文件属性
	int state;			//0建立,1打开
	int read_point;		//读写指针
	int write_point;
}UOF;

// 数据块 :		256B	34-100# 盘块
typedef struct cluster
{
	int  nowNum;			// 物理块号
	int  nextcluster;	// 指向下一个物理块
	int  has_data;		// 判断是否有数据
	char data[256];		// 数据
}Cluster;

typedef void(*func)(char**,int);
typedef struct hand
{
	const char* pname;
	func handler;
}HAND_TO;

#endif

1.2、main.cpp

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<conio.h>
#include "fileSystemStruct.h"
#define MAX_USER_NUM    10
#define MAX_FILE_NUM    10
#define MAX_CLUSTER_NUM 67
#define MAX_TRYLOGIN_TIME 3
const int COMMAND_LEN = 200;			//命令行最大长度
const int COMMAND_NUM = 12;			//命令条数
using namespace std;

vector<MFD>UserInfo;						//所有的用户
vector <vector<UFD> > FileInfo;				//所有文件信息
vector<vector<UOF> > FileState;				//所用用户打开的文件
vector<Cluster> FileCluster;				//磁盘块

int curID = 0;							   //默认第0号用户
int readingState = 0;						//文件阅读
int openingState = 0;						//文件打开

void Help();								//帮助
void initFileFromRom();						//从文件中读取
void outToFile();							//保存到文件
void split(char* src, const char* separator, char** dest, int* num);	//以某个字符串对字符串分割成数组
void shell();							    //终端
void handle(char* );						//选择函数并处理
void doLogin(char**,int);					//登录
void doLogout(char**,int);					//退出
void doCreate(char**,int);					//创建文件
void doWrite(char**, int);					//写文件
void doDelete(char**, int);					//删除文件
void doOpen(char**, int);					//查看文件
void doDir(char**, int);					//查看目录
void doRead(char**, int);					//查看部分
void doReadAll(char**, int);			    //查看全部
void doClose(char**, int);                  //关闭文件
void doRegister(char**, int);					//注册用户

HAND_TO handlerlist[] =
{
	{ "Login", doLogin},
	{"Logout",doLogout},
	{"Create",doCreate},
	{"Delete",doDelete},
	{"Write",doWrite},
	{"open",doOpen},
	{"dir",doDir},
	{"Read",doRead},
	{"ReadAll",doReadAll},
	{"Close",doClose},
	{"Register",doRegister}
};

int main() {
	initFileFromRom();						//从文件中读取
	Help();
	shell();
	outToFile();
}

void Help() {
	printf("欢迎使用由广大菜鸟完成的二级文件目录系统!\n");
	printf("******************************************\n");
	printf("Loin                              用户登陆\n");
	printf("Logout	                          用户登出\n");
	printf("Exit	                          退出系统\n");
	printf("Create 	xx.format  mode           创建文件\n");
	printf("Write  	xx.format                 填写文件\n");
	printf("Delete 	xx.format                 删除文件\n");
	printf("open   	xx.format                 打开文件\n");
	printf("Read   	xx.format   nbytes        查看文件\n");
	printf("ReadAll xx.format                 查看全部\n");
	printf("Close                             关闭文件\n");
	printf("dir                               查看目录\n");
	printf("Register userName userPwd         登记用户\n");
	printf("******************************************\n");
}

void initFileFromRom() {
	FILE* file;
	errno_t err; 
	if ((err = fopen_s(&file,"disk.txt", "r")) != 0) {  // 打开文件成功返回0,失败返回非0。
		fopen_s(&file, "disk.txt", "w");
		fclose(file);
		return;
	}	
	// 读入用户信息
	int userCount;		/*用户个数*/
	fscanf_s(file,"%d",&userCount);
	int i = 0,ret=0,j=0;
	MFD userItem;
	while( ( i<userCount) && (ret =fscanf_s(file, "%s %s %d",userItem.usrName,sizeof(userItem.usrName),userItem.usrPwd,sizeof(userItem.usrPwd),&userItem.link))!=-1 )
	{
		/* 这里获取的字符串,如果缺少长度的话,会出现运行时错误 */
		i += 1;
		UserInfo.push_back(userItem);
	}

	// 初始化文件信息
	/*	char creator[14];
		char filename[14];
		int mode;
		int length;
		int addr;
	*/
	UFD  fileInput;
	fileInput.addr = 0;
	strcpy_s(fileInput.filename,"");
	fileInput.length = 0;
	fileInput.mode = 0;			// 文件权限0 - readonly;  1 - writeonly;  2 - read / write
	vector<UFD>singleFileInfo;
	vector<UOF>singleFileState;
	for (j = 0; j < userCount; j++) {
		FileInfo.push_back(singleFileInfo);
		FileState.push_back(singleFileState);
	}
	int ufd_count;	
	for ( j = 0; j < userCount; j++) {
		fscanf_s(file, "%d", &ufd_count);
		i = 0;
		while( (i<ufd_count) && 
			((ret =	fscanf_s(file,"%s %s %d %d %d",
					fileInput.creator, sizeof(fileInput.creator),
					fileInput.filename,sizeof(fileInput.filename),
					&fileInput.mode,
					&fileInput.length, &fileInput.addr
			))!= -1 )  )
		{
			i++;		
			FileInfo[j].push_back(fileInput);
		}		
	}

	/*  char filename[14];
		int mode;
		int state; //0建立,1打开
		int read_poit; //读写指针
		int write_poit;
	*/
	UOF stateInput;
	strcpy_s(stateInput.filename, "");
	stateInput.mode = 0;	// 文件权限0 - readonly;  1 - writeonly;  2 - read / write
	stateInput.read_point = stateInput.write_point = 0;
	stateInput.state = 0;  //0建立,1打开
	
	for (j = 0; j < userCount; j++) {
		int uof_count;
		fscanf_s(file, "%d", &uof_count);
		i = 0;
		while ((i < uof_count) &&
			((ret = fscanf_s(file, "%s %s %d %d %d %d",
				stateInput.creator, sizeof(stateInput.creator),
				stateInput.filename, sizeof(stateInput.filename),
				&stateInput.mode, &stateInput.state,
				&stateInput.read_point, &stateInput.write_point
			)) != -1))
		{
			i++;
			FileState[j].push_back(stateInput);
		}
	}
	/*
	int  Num;			// 物理块号
	long nextcluster;	// 指向下一个物理块
	int  has_data;		// 判断是否有数据
	char data[256];		// 数据
*/
	char tmpBuffer[256];
	i = 0;
	Cluster clusterInput;
	char c;
	while (i < MAX_CLUSTER_NUM) {
		memset(tmpBuffer, 0, sizeof(tmpBuffer));
		if ((ret = fscanf_s(file,"%d %d", &clusterInput.nextcluster, &clusterInput.has_data))!=-1 ) {
			if (clusterInput.has_data == 1) {
				fscanf_s(file, "%c",&c );			/* 去掉一个空格*/
				fgets(tmpBuffer,256,file);
			}
			strcpy_s(clusterInput.data,tmpBuffer);
			FileCluster.push_back(clusterInput);
		}
		else {//初始化
			clusterInput.nextcluster = i;
			if (clusterInput.nextcluster >= MAX_CLUSTER_NUM)
				clusterInput.nextcluster = 0;
			clusterInput.has_data = 0;
			strcpy_s(clusterInput.data, tmpBuffer);
			FileCluster.push_back(clusterInput);
		}
		i++;
	}
	fclose(file);	
}

void outToFile() {
	FILE* file;
	errno_t err;
	if ((err = fopen_s(&file, "disk.txt", "w")) != 0) {  // 打开文件成功返回0,失败返回非0。
		printf("打开文件异常\n");
		return;
	}
	fprintf(file,"%d ",UserInfo.size());
	for (int i = 0; i < UserInfo.size(); i++)
		fprintf(file, "%s %s %d%c", UserInfo[i].usrName, UserInfo[i].usrPwd, UserInfo[i].link, ' ');
	fprintf(file, "\n");

	/*
	char filename[14];
	int mode;
	int length;
	int addr;
	*/
	for (int i = 0; i < FileInfo.size(); i++)
	{
		fprintf(file, "%d%c", FileInfo[i].size(), ' ');
		for (int j = 0; j < FileInfo[i].size(); j++)
		{
			fprintf(file, "%s %s %d %d %d%c", FileInfo[i][j].creator, FileInfo[i][j].filename,  FileInfo[i][j].mode, FileInfo[i][j].length, FileInfo[i][j].addr, ' ');
		}
		fprintf(file, "\n");
	}

	/*char filename[14];
	int mode;
	int state; //0建立,1打开
	int read_poit; //读写指针
	int write_poit;*/
	for (int i = 0; i < FileState.size(); i++)
	{
		fprintf(file, "%d%c", FileState[i].size(), ' ');
		for (int j = 0; j < FileState[i].size(); j++)
		{
			fprintf(file, "%s %s %d %d %d %d%c", FileState[i][j].creator,FileState[i][j].filename,  FileState[i][j].mode, FileState[i][j].state, FileState[i][j].read_point, FileState[i][j].write_point, ' ');
		}
		fprintf(file, "\n");
	}

	/*int num;
	int next_num;
	int is_data;
	char data[256];*/
	for (int i = 0; i < FileCluster.size(); i++)
	{
		fprintf(file, "%d %d%c", FileCluster[i].nextcluster, FileCluster[i].has_data, ' ');
		fputs(FileCluster[i].data, file); //和下面的一样都可以的
		//fprintf(file, "%s", FileCluster[i].data);
		fprintf(file, "\n");
	}
	fclose(file);
}

void shell() {
	char commandInput[COMMAND_LEN];
	while(true) {
		printf("system@%s:~$ ",UserInfo[curID].usrName);
		gets_s(commandInput);
		while ((strcmp(commandInput, "") == 0) || (strcmp(commandInput, "\n") == 0))
			gets_s(commandInput);
		if(strcmp(commandInput, "Exit") == 0)
			return;
		handle(commandInput);
	}
}

void split(char* src, const char* separator, char** dest, int* num) {
	/*
		src 源字符串的首地址(buf的地址)
		separator 指定的分割字符
		dest 接收子字符串的数组
		num 分割后子字符串的个数
	*/
	char* pNext;
	char *buf;
	int count = 0;
	if (src == NULL || strlen(src) == 0) //如果传入的地址为空或长度为0,直接终止 
		return;
	if (separator == NULL || strlen(separator) == 0) //如未指定分割的字符串,直接终止 
		return;
	pNext = (char*)strtok_s(src, separator,&buf); //必须使用(char *)进行强制类型转换(虽然不写有的编译器中不会出现指针错误)
	while (pNext != NULL) {
		*dest++ = pNext;
		++count;
		pNext = (char*)strtok_s(NULL, separator,&buf);  //必须使用(char *)进行强制类型转换
	}
	*num = count;
}

void handle(char * commandInput) {	
	char* args[3];
	int num;
	split(commandInput, " ", args, &num);
	if (num > 3) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}	
	for (int i = 0; i < COMMAND_NUM-1; i++) {
		if (strcmp(args[0], handlerlist[i].pname) == 0) {
			handlerlist[i].handler(args,num);
			return;
		}
	}
	printf("system@%s:~$ ", UserInfo[curID].usrName);
	printf("查无这条命令哦\n");
}

void doLogin(char**args,int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}	
	if (num > 1) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}

	int index = 0,sign=-1;
	int tryTime = MAX_TRYLOGIN_TIME;
	char ch, input_pwd[14],pwd[14],name[14];
	printf("system@%s:~$ Input your Name:", UserInfo[curID].usrName);
	scanf_s("%s",name,14);
	for (int i = 0; i < UserInfo.size(); i++) {
		if (strcmp(UserInfo[i].usrName, name) == 0) {
			strcpy_s(pwd, UserInfo[i].usrPwd);
			sign = i;
		}
	}
	if (sign == -1) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("该用户不存在\n");
		return;
	}
	while (tryTime--) {
		index = 0;
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("Input your password:");
		while ((ch = _getch()) != '\r') {
			if (ch == '\b' && index > 0) {
				printf("\b \b");		//空格+\b 是为了覆盖掉原来的字符 
				index--;
			}
			else if (ch != '\b') {
				input_pwd[index++] = ch;
			}
		}
		input_pwd[index] = '\0';
		if (strcmp(input_pwd, pwd) == 0) {
			printf("\nsystem@%s:~$ ", UserInfo[curID].usrName);
			printf("密码正确\n");
			curID = sign;
			return;
		}
		else {
			printf("\nsystem@%s:~$ ", UserInfo[curID].usrName);
			printf("密码不正确,请重试\n");
		}
	}
	printf("system@%s:~$ ", UserInfo[curID].usrName);
	printf("连续输入3次密码都不正确\n");
}

void doLogout(char** args,int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num > 1) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	
	curID = 0;
	printf("system@%s:~$ ", UserInfo[curID].usrName);
	printf("退出成功\n");
	return;
}

void doCreate(char**args,int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num != 3) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	//printf("system@%s:~$ ", UserInfo[curID].usrName);
	//printf("fileName=%s , mode=%s\n", args[1], args[2]);
	if (FileInfo[curID].size() >= MAX_FILE_NUM) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("该用户已经到达文件上限\n");
		return;
	}
	int isRepeat = 0,free = 0;
	for (int i = 0; i < FileInfo[curID].size(); i++) {
		if (strcmp(FileInfo[curID][i].filename, args[1]) == 0) {
			isRepeat = 1;
			break;
		}
	}
	if (isRepeat) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("文件重名\n");
		return;
	}
	UFD fileInput;
	strcpy_s(fileInput.creator,UserInfo[curID].usrName);
	strcpy_s(fileInput.filename, strlen(args[1])+1,args[1] );
	fileInput.mode = atoi(args[2]);
	fileInput.length = 0;
	//查找空闲的磁盘块存储
	for (int i = 0; i < FileCluster.size(); i++) {
		if (FileCluster[i].has_data == 0) {		//盘内没有数据
			fileInput.addr = i;
			FileCluster[i].has_data = 1;
			free = 1;
			break;
		}
	}
	if (!free) {
		printf("system@%s:~$ 文件失败,没有空闲空间\n", UserInfo[curID].usrName);
		return;
	}
	FileInfo[curID].push_back(fileInput);
	printf("system@%s:~$ 文件创建成功\n", UserInfo[curID].usrName);
	//状态栏
	UOF StateInput;
	strcpy_s(StateInput.creator,UserInfo[curID].usrName);
	strcpy_s(StateInput.filename,strlen(args[1])+1,args[1] );
	StateInput.mode = fileInput.mode;
	StateInput.read_point = StateInput.write_point = 0;
	StateInput.state = 0;
	FileState[curID].push_back(StateInput);
}

void doWrite(char** args, int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num != 2) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	char buf[1024],ch;
	char fileName[14];
	int exist = 0;
	int indexState = -1;				//FileState[curID][]中的序号
	int indexInfo = -1;			//FileInfo[curID][]的序号
	int address;				//文件对应起始的物理块
	int i;
	strcpy_s(fileName, strlen(args[1])+1, args[1]);
	for (i = 0; i < FileInfo[curID].size(); i++) {
		if (strcmp(FileInfo[curID][i].filename, fileName) == 0) {			
			if ((FileInfo[curID][i].mode == 0) || strcmp(FileInfo[curID][i].creator, UserInfo[curID].usrName) != 0 && FileState[curID][i].mode == 3) {
				printf("system@%s:~$ 当前用户对%s文件没有写的权限\n", UserInfo[curID].usrName, fileName);
				return;
			}
			exist = 1;
			address = FileInfo[curID][i].addr;
			indexInfo = i;
			break;
		}
	}
	if (!exist) {
		printf("system@%s:~$ %s文件不存在\n", UserInfo[curID].usrName, fileName);
		return;
	}
	for (i = 0; i < FileState[curID].size(); i++) {
		if (strcmp(FileState[curID][i].filename,fileName) == 0) {
			indexState  = i;
			break;
		}
	}
	if (indexState == -1) { //代表fileState找不到vector<UOF>对象
		UOF tmp;
		strcpy_s(tmp.creator, FileInfo[curID][indexInfo].creator);
		strcpy_s(tmp.filename, FileInfo[curID][indexInfo].filename);
		tmp.mode = FileInfo[curID][indexInfo].mode;
		tmp.read_point = tmp.write_point = 0;
		tmp.state = 0;
		FileState[curID].push_back(tmp);
		for (i = 0; i < FileState[curID].size(); i++) {
			if (strcmp(FileState[curID][i].filename, fileName) == 0) {
				indexState = i;
				break;
			}
		}
	}
	printf("====进入写文件状态,使用ctrl+s退出写状态====\n");
	int needNewDiskNum=0;
	vector<char>textList;
	while ((ch =getchar() )!=(char)19) {
		textList.push_back(ch);
	}
	int txtSize= textList.size();
	int wbegin = FileState[curID][indexState].write_point;
	while (FileCluster[address].nextcluster != address) {//最后一个磁盘的下一个指向自己
		address = FileCluster[address].nextcluster;
	}
	/*  计算需要的磁盘数量 */
	vector<int>newSpaceIndexList;
	if (txtSize <= 256 - wbegin) {	//判断是否足够插入原来的磁盘
		needNewDiskNum = 0;
	}
	else {
		needNewDiskNum =ceil( (txtSize - (256 - wbegin))*1.0 / 256);
	}
	newSpaceIndexList.push_back(address);
	/* 最先适应算法,选择足够的磁盘 */
	for (i = 0; i < FileCluster.size(); i++) {
		if (newSpaceIndexList.size() == needNewDiskNum + 1)
			break;
		if (FileCluster[i].has_data == 0) {
			newSpaceIndexList.push_back(i);
			FileCluster[i].has_data = 1;
		}
	}
	/* 修改选中磁盘的下一个 */
	for (int k = 0; k < newSpaceIndexList.size()-1; i++) {
		FileCluster[newSpaceIndexList[k]].nextcluster = newSpaceIndexList[k + 1];
	}
	/*  填入信息到磁盘    */
	for (i = 0; i < txtSize; i++) {
		if (wbegin == 256) {
			wbegin = 0;
			address = FileCluster[address].nextcluster;
		}
		FileCluster[address].data[wbegin] = textList[i];
			wbegin++;			
	}
	FileCluster[address].data[wbegin] = '\0';
	wbegin++;
	FileInfo[curID][indexInfo].length = txtSize;
	/*   更新写指针    */
	FileState[curID][indexState].write_point = wbegin;
	printf("========退出写文件状态,且保存磁盘=========\n");
}

void doDelete(char** args, int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num != 2) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	char fileName[14];
	strcpy_s(fileName, strlen(args[1]) + 1, args[1]);
	int exist = 0,i=0,tmp=-1;
	for (i = 0; i < FileInfo.size(); i++) {
		if (strcmp(FileInfo[curID][i].filename, fileName) == 0) {
			if (strcmp(FileInfo[curID][i].creator, UserInfo[curID].usrName) != 0) {
				printf("system@%s:~$ 当前用户对该文件没有删除的权限\n", UserInfo[curID].usrName);
				return;
			}
			exist = 1;
			break;
		}
	}
	if (!exist) {
		printf("system@%s:~$ 文件不存在\n", UserInfo[curID].usrName);
		return;
	}
	int address;//文件存放的磁盘起始块号
	int index;	
	/*    清除用户文件信息     */
	for (i = 0; i < FileInfo[curID].size(); i++) {
		if (strcmp(fileName, FileInfo[curID][i].filename) == 0) {
			address = FileInfo[curID][i].addr;
			index = i;
			break;
		}
	}
	vector <UFD> ::iterator  iter = FileInfo[curID].begin() + index;
	FileInfo[curID].erase(iter);

	/*     清除磁盘记录        */
	/* 获取磁盘写的长度*/
	for (i = 0; i < FileState[curID].size(); i++) {
		if (strcmp(fileName, FileState[curID][i].filename) == 0) {
			index = i;
			break;
		}
	}

	while (1) {
		if (FileCluster[address].nextcluster == address) {	//最后一块
			for (i = 0; i < FileState[curID][index].write_point; i++) {
				FileCluster[address].data[i] = 0;
			}
			FileCluster[address].has_data = 0;
			FileCluster[address].nextcluster = address;
			break;
		}
		else {
			for (i = 0; i < 256; i++) {
				FileCluster[address].data[i] = 0;
			}
			FileCluster[address].has_data = 0;
			tmp = address;
			address = FileCluster[address].nextcluster;
			FileCluster[tmp].nextcluster = tmp;
		}
	}

	vector <UOF> ::iterator  iter1 = FileState[curID].begin() + index;
	FileState[curID].erase(iter1);
}

void doDir(char** args, int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num != 1) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	if (FileInfo[curID].size() == 0) {
		return;
	}
	printf("system@%s:~$ 目录内容如下;\n", UserInfo[curID].usrName);
	for (int i = 0; i < FileInfo[curID].size(); i++)
	{
		if(i==0)
			printf("%s %s\n", FileInfo[curID][i].filename,FileInfo[curID][i].creator);
		else 
			printf("\t\t\t%s %s\n", FileInfo[curID][i].filename, FileInfo[curID][i].creator);
	}
	printf("\n");
}

void doOpen(char** args, int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num != 2) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	/*  判断是否有权限  */
	int exit = 0,i=0,j=0;
	for (i = 0; i < FileState[curID].size(); i++) {
		if (strcmp(FileState[curID][i].filename, args[1])==0) {
			exit = 1;
			FileState[curID][i].state = 1;//打开状态
			break;
		}
	}
	UOF tmp;
	if (!exit) {	//需要在UFD中打开
		for (j = 0; j < FileInfo[curID].size(); j++) {
			if (strcmp( FileInfo[curID][j].filename, args[1])==0) {
				exit = 1;
				strcpy_s(tmp.creator, FileInfo[curID][j].creator);
				strcpy_s(tmp.filename, args[1]);
				tmp.mode = FileInfo[curID][j].mode;
				tmp.read_point = tmp.write_point = 0;
				tmp.state = 1;
				FileState[curID].push_back(tmp);
				break;
			}
		}
	}
	if (!exit) {
		printf("system@%s:~$ 文件不存在\n", UserInfo[curID].usrName);
		return;
	}
	/* 判断权限 */
	if (strcmp(FileState[curID][i].creator,UserInfo[curID].usrName) != 0 && FileState[curID][i].mode ==3 ) {
		printf("system@%s:~$ 当前用户对该文件没有访问的权限\n", UserInfo[curID].usrName);
		return;
	}	
	openingState = 1;
}

void doReadAll(char** args, int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num != 2) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	int length=0;
	for (int i = 0; i < FileInfo[curID].size(); i++) {
		if (strcmp(FileInfo[curID][i].filename, args[1]) == 0) {
			length = FileInfo[curID][i].length;
			break;
		}
	}
	char* Args[3],tmp[14];
	Args[0] = args[0];
	Args[1] = args[1];
	_itoa_s(length,tmp,10);
	Args[2] = tmp;
	doRead( Args,  num+1);
}

void doRead(char** args, int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num != 3) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	/*  判断是否有权限  */
	int exit = 0, i = 0, address = -1, index = -1, length = atoi(args[2]);
	for (i = 0; i < FileState[curID].size(); i++) {
		if (strcmp(FileState[curID][i].filename, args[1])==0) {
			/* 判断权限 */
			if (strcmp(FileState[curID][i].creator, UserInfo[curID].usrName) != 0 && FileState[curID][i].mode == 3) {
				printf("system@%s:~$ 当前用户对该文件没有访问的权限\n", UserInfo[curID].usrName);
				return;
			}
			/* 判断权限 */
			if (FileState[curID][i].mode == 1) {
				printf("system@%s:~$ 当前用户对该文件没有读的权限\n", UserInfo[curID].usrName);
				return;
			}
			if (FileState[curID][i].state != 1) {
				printf("system@%s:~$ 该文件没有打开,请打开后再进行读操作\n", UserInfo[curID].usrName);
				return;
			}
			exit = 1;
			FileState[curID][i].state = 1;//打开状态
			index = i;
			break;
		}
	}
	if (!exit) {
		printf("system@%s:~$ 文件不存在或没打开\n", UserInfo[curID].usrName);
		return;
	}
	readingState = 1;
	for (i = 0; i < FileInfo[curID].size(); i++) {
		if (strcmp(FileInfo[curID][i].filename, args[1]) == 0) {
			address = FileInfo[curID][i].addr;
			if (FileInfo[curID][i].length == 0) {
				return;
			}
			break;
		}
	}
	if (FileInfo[curID][i].length == FileState[curID][index].read_point) {	//防止上次读完后不能选择重新开始读
		FileState[curID][index].read_point = 0;
	}
	int rbegin = FileState[curID][index].read_point;
	int readedDisk = rbegin / 256;			//读过的磁盘数
	for (i = 0; i < readedDisk; i++) {
		address = FileCluster[address].nextcluster;
	}
	vector<char>textList;
	for (i = 0; i < length; i++) {
		if (rbegin % 256 == 255) {
			address = FileCluster[address].nextcluster;
		}
		textList.push_back(FileCluster[address].data[i%256]);
		rbegin++;
	}
	FileState[curID][index].read_point = rbegin;
	for (int i = 0; i < length; i++) {
		printf("%c", textList[i]);
	}
	printf("\n");
}

void doClose(char** args, int num) {
	if (!openingState) {
		printf("system@%s:~$ 没有打开的文件\n", UserInfo[curID].usrName);
		return;
	}
	readingState = 0;					
	openingState = 0;
	if (num != 2) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	vector<UOF>::iterator it;
	int flag = 0;
	for (it = FileState[curID].begin(); it != FileState[curID].end(); it++) {
		if (strcmp(args[1], (*it).filename) == 0 ) {
			if ((*it).state == 1) {
				flag = 1;
				FileState[curID].erase(it);
				printf("system@%s:~$ 该文件已经关闭\n", UserInfo[curID].usrName);
				return;
			}
			else {
				printf("system@%s:~$ 该文件没有打开\n", UserInfo[curID].usrName);
				return;
			}
		}
	}
	if (!flag) {
		printf("system@%s:~$ 该目录下没有这个文件\n", UserInfo[curID].usrName);
		return;
	}


}

void doRegister(char** args, int num) {
	if (readingState) {
		printf("system@%s:~$ 有文件在进行写操作,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	else if (openingState) {
		printf("system@%s:~$  有文件已经打开,请关闭后再进行其他操作\n", UserInfo[curID].usrName);
		return;
	}
	if (num !=3 ) {
		printf("system@%s:~$ ", UserInfo[curID].usrName);
		printf("参数错误哦\n");
		return;
	}
	if (UserInfo.size() > MAX_USER_NUM) {
		printf("system@%s:~$ 用户人数已满,无法注册\n", UserInfo[curID].usrName);
		return;
	}
	int i = 0;
	for (i = 0; i < UserInfo.size(); i++) {
		if (strcmp(args[1], UserInfo[i].usrName) == 0) {
			printf("system@%s:~$ 用户重名,无法注册\n", UserInfo[curID].usrName);
			return;
		}
	}
	MFD userInput;
	strcpy_s(userInput.usrName,args[1] );
	strcpy_s(userInput.usrPwd, args[2]);
	userInput.link = UserInfo.size();
	UserInfo.push_back(userInput);

	//为新的用户开辟空间
	vector<UFD>t;
	FileInfo.push_back(t);

	vector<UOF>temp;
	FileState.push_back(temp);
	printf("system@%s:~$ 用户创建成功\n", UserInfo[curID].usrName);
	return;
}

2、学习到新知识分享

2.1、函数指针的使用–C的进阶

typedef void(*func)(char**,int);
typedef struct hand
{
	const char* pname;
	func handler;
}HAND_TO;

HAND_TO handlerlist[] =
{
	{ "Login", doLogin},
	{"Logout",doLogout},
	{"Create",doCreate},
	{"Delete",doDelete},
	{"Write",doWrite},
	{"open",doOpen},
	{"dir",doDir},
	{"Read",doRead},
	{"ReadAll",doReadAll},
	{"Close",doClose},
	{"Register",doRegister}
};
for (int i = 0; i < COMMAND_NUM-1; i++) {
		if (strcmp(args[0], handlerlist[i].pname) == 0) {
			handlerlist[i].handler(args,num);
			return;
		}
	}

通过这种方式可以节省if-else ,switch代码量,而且非常容易增删

2.2、用户登录密码不回显

我另一篇博客提到2种方法
C语言分别实现在Linux和window的输入不回显

2.3、终端获取多个参数,并存储于二级数组

void split(char* src, const char* separator, char** dest, int* num) {
	/*
		src 源字符串的首地址(buf的地址)
		separator 指定的分割字符
		dest 接收子字符串的数组
		num 分割后子字符串的个数
	*/
	char* pNext;
	char *buf;
	int count = 0;
	if (src == NULL || strlen(src) == 0) //如果传入的地址为空或长度为0,直接终止 
		return;
	if (separator == NULL || strlen(separator) == 0) //如未指定分割的字符串,直接终止 
		return;
	pNext = (char*)strtok_s(src, separator,&buf); //必须使用(char *)进行强制类型转换(虽然不写有的编译器中不会出现指针错误)
	while (pNext != NULL) {
		*dest++ = pNext;
		++count;
		pNext = (char*)strtok_s(NULL, separator,&buf);  //必须使用(char *)进行强制类型转换
	}
	*num = count;
}
//使用案例
	char* args[3];
	int num;
	split(commandInput, " ", args, &num);

2.4、模拟终端输入并保存后退出

非常简单,就是判断输入的字符是否为目的退出字符
ctrl+s =(char)19

char ch;
vector<char>textList;
	while ((ch =getchar() )!=(char)19) {
		textList.push_back(ch);
	}

可以同行也可以不同行
在这里插入图片描述
在这里插入图片描述

ctrl+z=(char)-1

vectortextList;

char ch;
printf("%c", NULL);
while ((ch = getchar()) != (char)-1) {
	textList.push_back(ch);
}
for (int i = 0; i < textList.size(); i++) {
	printf("%c",textList[i]);
}

可以换行,但不能同行
在这里插入图片描述

在这里插入图片描述
这个ctrl+z的原因暂时还没找到。

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
共两个不同设计例子,都含详细的文档资料。 任务2.设计一个简单的二级文件系统 设计要求: 在任一OS下,建立一个大文件,把它假象成硬盘,在其中实现一个简单的模拟文件系统。 编写一管理程序对此空间进行管理,要求: 1. 实现盘块管理 2. 实现文件的读写操作 3. 每组最多2人,小组内要有明确分工,课程设计报告中设计部分可以相同,个人实现部分不同 参考建议: 将模拟硬盘的文件空间划分为目录区,文件区;采用位示图进行空间管理,盘块的分配使用显示链接(FAT表)的方式。 设计技术参数(数据结构)参考: #define MaxSize 100 #define Disk 512 //每个盘块大小为512bit #define NumDisk 2048 //有2048个盘块,既可分配空间为 1M /*************目录和文件的结构定义***********************/ struct DirectoryNode { char name[9]; /*目录或文件的名字*/ int type; /*0代表目录,1代表普通文件*/ struct DirectoryNode *next; /*指向下一个兄弟结点的指针*/ struct DirectoryNode *preDirFile; /*指向父结点的指针*/ struct DirectoryNode *subFile; /*指向第一个子结点的指针*/ int size; /*如果是文件则表示文件的大小*/ int first; /*起始盘块号*/ int last; /*末尾盘块号*/ int order; /*备用*/ }; //连续分配 struct FileSys { int VacTable[NumDisk]; //空闲表,0为空闲,1为被用 struct DirectoryNode root; //根目录 struct DirectoryNode Directory[NumDisk]; } *filesys; typedef struct { struct DirectoryNode *DirFile; char name[9]; }DataType; //包含一个指向目录的指针和名字 typedef struct { //队列结构的实现 DataType data[MaxSize]; int front,rear; //分别表示队列的头结点和尾结点 }Tp; void InitQueue(Tp *sq) //队列初始化 int EnAddQueue(Tp *sq,DataType data) //在队列中增加元素 DataType EnDelQueue(Tp *sq) //从队列中删除一个元素 int Empty(Tp *sq) //判断队列是否为空,返回0表示队列为空 ①.Dir:显示目录内容命令,显示当前目录下的文件和子目录。 ②.Md:创建目录操作。 ③.Create:创建文件,在当前目录下创建一个文件。 ④. all:显示从根目录开始的所有目录和文件及其层次结点。 ⑤.Cd:改变目录。 ⑥.Del:删除文件操作。 ⑦. Rd:删除目录操作,删除当前目录下的子目录。 ⑧. Ren:重命名函数 ⑨. Exit:退出命令
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值