操作系统课程设计—linux文件系统(索引节点结构)的模拟实现

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include "windows.h"
using namespace std;

void reload();                          //重载内存
void format();                          //磁盘格式化
void Init_FreeBlock();                  //初始化空闲块
int Allocate_FreeBlock();               //空闲块分配
void Reclaim_FreeBlock(int i);          //空闲块回收
int Allocate_flist();                   //文件列表分配
void Reclaim_flist(int id);             //打开文件列表回收
int Allocate_finode();                  //打开文件的索引列表分配
void Reclaim_finode(int id);            //打开文件的索引列表回收
int Allocate_inode();                   //索引节点分配
void Reclaim_inode(int id);             //索引节点回收
int SerchList(char *name,int format);   //查找当前目录
int openf(char *name);                  //打开文件
void close(char *name);                 //关闭文件
void mkdir(char *name);                 //创建目录
void rmdir(char *name);                 //删除目录
void creatfile(char *name);             //创建文件
void delfile(char *name);               //删除文件
void write(char *name);                 //写入文件
void listshow();                        //显示当前目录内文件简略信息
void ShowOpen();                        //显示当前已打开的文件
void ShowDetails();                     //显示当前目录内文件详细信息
void switchDir(char *name);             //目录切换
void Time_format(time_t ntime);         //时间格式转换
void cread(char *name);                 //查看文件
void Cut(char *name);                   //剪切文件
void Copy(char *name);                  //复制文件
void Paste();                           //粘贴文件
void exit();                            //保存并退出

const int BlockSize = 512;              //物理块大小(字节)
const int BlockNum = 128;               //物理块个数
const int OpenfileNum = 10;             //最多可同时打开的文件数
const int BufSize = 512;                //缓冲区大小(字节)
const int SuperBlockSize = 10;          //超级块栈内大小(可存储空闲块的个数)

struct inode
{
	char name[14];
	int id;			//inode标号
	int size;		//文件大小
	int fredir;		//上级目录的索引节点号
	int curdir;		//当前目录的索引节点号
	int format;		//文件格式,1--目录文件,2--普通文件
	time_t fixtime;	//最近一次修改时间
	int Block[5];   //数据块,文件所占的物理块(目录文件只占首块)
	void clear()
	{
		strcpy(name,"\0");
		id = 0;
		fredir = 0;
		curdir = 0;
		size = 0;
		format = 0;
		fixtime = 0;
		for(int i = 0; i < 5; i++){
            Reclaim_FreeBlock(Block[i]);
            Block[i] = -1;
		}
	}
};

struct FN				//文件控制块
{
	char name[14];		//文件名
	int fnodeID;		//常驻内存的索引节点指针
	int inode_id;		//文件索引节点号
};

const int fcbCount = (BlockSize-sizeof(FN))/sizeof(FN);

struct dirFile
{
	FN dfcb;
	FN list[fcbCount];
	void init(int _curdir, char *name)
	{
		strcpy(dfcb.name,name);
		dfcb.fnodeID = _curdir;
		for(int i = 0; i < fcbCount; i++){
			list[i].fnodeID = -1;
		}
	}
};

struct DISK
{
    char Password[40];
	int GPT[BlockNum];
	dirFile root;
	char data[BlockNum][BlockSize];
	inode _nodelist[BlockNum];
	bool _nodelist_vis[BlockNum];
	int _inode_cnt;
	void format()
	{
	    memset(GPT,0,sizeof GPT);
	    memset(data,0,sizeof data);
	    GPT[0] = GPT[1] = 1;
	    root.init(1,"root");
	}
};

struct CP_board
{
    int flag;                   //剪贴板标志位,0为空,1为复制,2为剪切
    inode cp_inode;             //暂存索引节点信息
    CP_board()
    {
        flag = 0;
    }
};

FILE *fp;                                           //虚拟磁盘保存文件
char DiskPath[40] = "D://mytest//";                 //虚拟磁盘路径
char *BaseAddr;                                     //虚拟磁盘的实际地址
char curPath[100]={"root:\\>"};                     //虚拟地址路径
DISK *Disk;                                         //虚拟磁盘
time_t nowtime;										//当前系统时间
int curpoint = 0;									//系统指针,记录当前所在的位置
int SuperBlock[SuperBlockSize], top=0;
FN flist[OpenfileNum];
inode finode[OpenfileNum];
inode nodelist[BlockNum];
int flist_cnt, finode_cnt, buf_size, freeblock_cnt, inode_cnt;
bool finode_vis[OpenfileNum], flist_vis[OpenfileNum], nodelist_vis[BlockNum];
char buf[BufSize];
CP_board Clipboard;

void reload()
{
	curpoint = 0;
    memcpy(nodelist,Disk->_nodelist,sizeof(nodelist));
    memcpy(nodelist_vis,Disk->_nodelist_vis,sizeof(nodelist_vis));
    inode_cnt = Disk->_inode_cnt;
    Init_FreeBlock();
}

void format()
{
	curpoint = 0;
	printf("正在进行格式化...\n");
	Disk->format();
	for(int i = 0; i < BlockNum; i++){
		nodelist[i].clear();
	}
	memset(nodelist_vis,0,sizeof(nodelist_vis) );
	inode_cnt = 0;
	strcpy(curPath,"root://");
	inode_cnt--;
	nodelist[0].clear();
	nodelist_vis[0] = 1;
	nodelist[0].Block[0] = 1;
	nodelist[0].curdir = 0;
	nodelist[0].format = 1;
	nodelist[0].fredir = 0;
	strcpy(nodelist[0].name,"root");
	Init_FreeBlock();
	memcpy(Disk->_nodelist,nodelist,sizeof(nodelist));
    memcpy(Disk->_nodelist_vis,nodelist_vis,sizeof(nodelist_vis));
    Disk->_inode_cnt = inode_cnt;
	fp = fopen(DiskPath,"w+");
	fwrite(BaseAddr,sizeof(char),sizeof(DISK),fp);
	fclose(fp);
	printf("格式化已完成.\n");
}

void Init_FreeBlock()
{
	int i,j;
	for(i = 2; i < BlockNum; i++)
	{
		if(Disk->GPT[i] == 0){
			if(top==SuperBlockSize){
				for(j = 0; j < SuperBlockSize; j++){
					Disk->data[i][j*4] = (char)(SuperBlock[j]/1000+'0');
					SuperBlock[j]%=1000;
					Disk->data[i][j*4+1] = (char)(SuperBlock[j]/100+'0');
					SuperBlock[j]%=100;
					Disk->data[i][j*4+2] = (char)(SuperBlock[j]/10+'0');
					SuperBlock[j]%=10;
					Disk->data[i][j*4+3] = (char)(SuperBlock[j]+'0');
				}
				top=0;
			}
			SuperBlock[top++]=i;
			//printf("%d ",SuperBlock[top-1]);
			freeblock_cnt++;
		}
	}
}

int Allocate_FreeBlock()
{
	if(freeblock_cnt == 0)return -1;
	freeblock_cnt--;
	if(top == 1){
        top--;
		int i = SuperBlock[top];
		for(int j = 0; j < SuperBlockSize; j++){
            SuperBlock[j] = 0;
            SuperBlock[j] += (int)(Disk->data[i][j*4]-'0');
            SuperBlock[j] *=10;
            SuperBlock[j] += (int)(Disk->data[i][j*4+1]-'0');
            SuperBlock[j] *=10;
            SuperBlock[j] += (int)(Disk->data[i][j*4+2]-'0');
            SuperBlock[j] *=10;
            SuperBlock[j] += (int)(Disk->data[i][j*4+3]-'0');
            //printf("%d ",SuperBlock[j]);
		}
		top = SuperBlockSize;
		Disk->GPT[i] = 1;
		memset(Disk->data[i],0,sizeof(BlockSize));
		return i;
	}else{
		top--;
		Disk->GPT[SuperBlock[top]] = 1;
		memset(Disk->data[SuperBlock[top]],0,sizeof(BlockSize));
		return SuperBlock[top];
	}
}


void Reclaim_FreeBlock(int i)
{
	if(Disk->GPT[i] == 0)return;
	freeblock_cnt++;
	if(top == SuperBlockSize){
		for(int j = 0; j < SuperBlockSize; j++){
			Disk->data[i][j*4] = (char)(SuperBlock[j]/1000+'0');
			SuperBlock[j]%=1000;
			Disk->data[i][j*4+1] = (char)(SuperBlock[j]/100+'0');
			SuperBlock[j]%=100;
			Disk->data[i][j*4+2] = (char)(SuperBlock[j]/10+'0');
			SuperBlock[j]%=10;
			Disk->data[i][j*4+3] = (char)(SuperBlock[j]+'0');
		}
		top=0;
	}
	SuperBlock[top++]=i;
	Disk->GPT[i] = 0;
}

int Allocate_flist()
{
	if(flist_cnt+1 >=OpenfileNum)return -1;
	flist_cnt++;
	int id;
	for(int i = 0; i < OpenfileNum; i++)
	{
		if(flist_vis[i] == 0){
			id=i;
            flist_vis[id] = 1;
			break;
		}
	}
	return id;
}

void Reclaim_flist(int id)
{
	flist_vis[id] = 0;
	flist_cnt--;
}

int Allocate_finode()
{
	if(finode_cnt+1 >=OpenfileNum)return -1;
	finode_cnt++;
	int id;
	for(int i = 0; i < OpenfileNum; i++)
	{
		if(finode_vis[i] == 0){
			id=i;
            finode_vis[id] = 1;
			break;
		}
	}
	return id;
}

void Reclaim_finode(int id)
{
	finode_vis[id] = 0;
	finode_cnt--;
}

int Allocate_inode()
{
	if(inode_cnt+1 >= BlockNum)return -1;
	inode_cnt++;
	int id;
	for(int i = 0; i < BlockNum; i++)
	{
		if(nodelist_vis[i] == 0){
			id=i;
            nodelist_vis[id] = 1;
			break;
		}
	}
	return id;
}

void Reclaim_inode(int id)
{
	nodelist_vis[id] = 0;
	inode_cnt--;
}

int SerchList(char *name,int format)
{
	dirFile *dir;
	int current = nodelist[curpoint].Block[0];
	if( current == 1){
		dir = &Disk->root;
	}else{
		dir = (dirFile *)(Disk->data[current]);
	}
	for(int i = 0; i < fcbCount; i++)
	{
		if(nodelist[dir->list[i].fnodeID].format == format&&strcmp(dir->list[i].name,name)==0)
            return dir->list[i].fnodeID;
	}
	return -1;
}

int openf(char *name)
{
	for(int i = 0; i < OpenfileNum; i++)
	{
		if(flist_vis[i] && strcmp(name,flist[i].name) == 0)
		{
		    printf("文件%s已打开\n",name);
			return -1;
		}
	}
	int rt = SerchList(name,2);
	int fd,fdnode;
	if(rt < 0){
		printf("此目录下未找到该文件\n");
		return -1;
	}else{
		fd = Allocate_flist();
		if(fd == -1)
		{
			printf("同时打开的文件数达到上限\n");
			return -1;
		}else{
			fdnode = Allocate_finode();
			if(fdnode == -1)
			{
				printf("当前系统资源不足,无法打开文件\n");
				Reclaim_flist(fd);
				return -1;
			}else{
				finode[fdnode] = nodelist[rt];
				flist[fd].fnodeID = fdnode;
				flist[fd].inode_id = rt;
				strcpy(flist[fd].name,name);
				printf("文件%s打开成功\n",flist[fd].name);
				return fd;
			}
		}
	}
}

void close(char *name)
{
	for(int i = 0; i < OpenfileNum; i++)
	{
		if(flist_vis[i] && strcmp(name,flist[i].name) == 0)
		{
			nodelist[flist[i].inode_id] = finode[flist[i].fnodeID];
			Reclaim_finode(flist[i].fnodeID);
			Reclaim_flist(i);
			printf("文件关闭成功\n");
			return;
		}
	}
	printf("文件尚未打开\n");
	return;
}

void mkdir(char *name)
{
	dirFile *dir;
	int current = nodelist[curpoint].Block[0];
	if(current == 1){
		dir = &Disk->root;
	}else{
		dir = (dirFile *)(Disk->data[current]);
	}
	for(int i = 0; i < fcbCount; i++){
		if(dir->list[i].fnodeID != -1&&nodelist[dir->list[i].fnodeID].format == 1&&strcmp(dir->list[i].name,name) == 0)
		{
			printf("此文件夹下已有同名文件夹\n");
			return;
		}
	}
	int list_id = -1;
	for(int i = 0; i < fcbCount; i++){
		if(dir->list[i].fnodeID == -1)
		{
			list_id = i;
			break;
		}
	}
	if(list_id == -1)
	{
		printf("此文件夹下的目录项已满\n");
		return;
	}
	int inode_id,newBlock;
	inode_id = Allocate_inode();
	if(inode_id == -1){
		printf("磁盘文件项已满,无法继续创建\n");
		return;
	}else{
		newBlock = Allocate_FreeBlock();
        //printf("inode_id:%d newBlock:%d\n",inode_id,newBlock);
		if(newBlock == -1){
			printf("磁盘空间不足!\n");
			Reclaim_inode(inode_id);
			return;
		}else{
			Disk->GPT[newBlock] = 1;
			strcpy(dir->list[list_id].name,name);
			dir->list[list_id].fnodeID = inode_id;
			strcpy(nodelist[inode_id].name,name);
			nodelist[inode_id].format = 1;
			nodelist[inode_id].fredir = curpoint;
			nodelist[inode_id].curdir = inode_id;
			nodelist[inode_id].Block[0] = newBlock;
			nowtime = time(0);
			nodelist[inode_id].fixtime = nowtime;
			nodelist[dir->dfcb.fnodeID].fixtime = nowtime;
			dir = (dirFile *)(Disk->data[newBlock]);
			dir->init(inode_id,name);
			return;
		}
	}
}

void rmdir(char *name)
{
	dirFile *dir;
	int current = nodelist[curpoint].Block[0];
	if(current == 1){
		dir = &Disk->root;
	}else{
		dir = (dirFile *)(Disk->data[current]);
	}
	int list_id = -1;
	for(int i = 0; i < fcbCount; i++){
		if(dir->list[i].fnodeID != -1&&nodelist[dir->list[i].fnodeID].format == 1&&strcmp(dir->list[i].name,name) == 0)
		{
			list_id = i;
		}
	}
	if(list_id == -1)
	{
		printf("此文件夹下未找到该文件夹\n");
		return;
	}
	int son_inode,son_block;
	dirFile *sondir;
	son_inode = dir->list[list_id].fnodeID;
	son_block = nodelist[son_inode].Block[0];
	sondir = (dirFile *)(Disk->data[son_block-2]);
	for(int i = 0; i < fcbCount; i++){
		if(sondir->list[i].fnodeID != -1)
		{
			printf("此文件夹尚未清空,请清空后再删除\n");
			return;
		}
	}
	char *p = Disk->data[son_block];
	memset(p,0,BlockSize);
	Reclaim_FreeBlock(son_block);
	Disk->GPT[son_block] = 0;
	Reclaim_inode(dir->list[list_id].fnodeID);
	dir->list[list_id].fnodeID = -1;
	return;
}

void creatfile(char *name)
{
	dirFile *dir;
	int current = nodelist[curpoint].Block[0];
	if(current == 1){
		dir = &Disk->root;
	}else{
		dir = (dirFile *)(Disk->data[current]);
	}
	for(int i = 0; i < fcbCount; i++){
		if(dir->list[i].fnodeID != -1&&nodelist[dir->list[i].fnodeID].format == 2&&strcmp(dir->list[i].name,name) == 0)
		{
			printf("此文件夹下已有同名文件\n");
			return;
		}
	}
	int list_id = -1;
	for(int i = 0; i < fcbCount; i++){
		if(dir->list[i].fnodeID == -1)
		{
			list_id = i;
			break;
		}
	}
	if(list_id == -1)
	{
		printf("此文件夹下的目录项已满\n");
		return;
	}
	int inode_id,newBlock;
	inode_id = Allocate_inode();
	if(inode_id == -1){
		printf("磁盘文件项已满,无法继续创建\n");
		return;
	}else{
		newBlock = Allocate_FreeBlock();
		if(newBlock == -1){
			printf("磁盘空间不足!\n");
			Reclaim_inode(inode_id);
			return;
		}else{
			Disk->GPT[newBlock] = 1;
			strcpy(dir->list[list_id].name,name);
			dir->list[list_id].fnodeID = inode_id;
			strcpy(nodelist[inode_id].name,name);
			nodelist[inode_id].format = 2;
			nodelist[inode_id].fredir = curpoint;
			nodelist[inode_id].curdir = inode_id;
			nodelist[inode_id].Block[0] = newBlock;
			nowtime = time(0);
			nodelist[inode_id].fixtime = nowtime;
			nodelist[dir->dfcb.fnodeID].fixtime = nowtime;
			dir = (dirFile *)(Disk->data[newBlock]);
			dir->init(inode_id,name);
		}
	}
}

void delfile(char *name)
{
	dirFile *dir;
	int current = nodelist[curpoint].Block[0];
	if(current == 1){
		dir = &Disk->root;
	}else{
		dir = (dirFile *)(Disk->data[current]);
	}
	int list_id = -1;
	for(int i = 0; i < fcbCount; i++){
		if(dir->list[i].fnodeID != -1&&nodelist[dir->list[i].fnodeID].format == 2&&strcmp(dir->list[i].name,name) == 0)
		{
			list_id = i;
		}
	}
	if(list_id == -1)
	{
		printf("此文件夹下未找到该文件\n");
		return;
	}
	int son_inode,son_block;
	son_inode = dir->list[list_id].fnodeID;
	son_block = nodelist[son_inode].Block[0];
	char *p = Disk->data[son_block];
	memset(p,0,BlockSize);
	Reclaim_FreeBlock(son_block);
	Disk->GPT[son_block] = 0;
	Reclaim_inode(dir->list[list_id].fnodeID);
	dir->list[list_id].fnodeID = -1;
	return;
}

void write(char *name)
{
	int fd = -1;
	for(int i = 0; i < OpenfileNum; i++)
	{
		if(flist_vis[i] && strcmp(name,flist[i].name) == 0)
		{
			fd = i;
			break;
		}
	}
	if(fd == -1){
		printf("该文件未打开\n");
	}else{
	    int inode_id = flist[fd].fnodeID;
	    int maxSize = BlockSize*5 - finode[inode_id].size;
	    printf("此文件剩余可写空间为%d字节,请输入要写入的信息,以Ctrl + D结束\n",maxSize);
        char x;
        do{
            x = getchar();
            if(x != 4)buf[buf_size++] = x;
            if(buf_size > maxSize){
                printf("文件剩余可用空间不足,写入终止\n");
                return;
            }
            if(buf_size == BlockSize || x == 4){
                if(finode[inode_id].size%BlockSize + buf_size > BlockSize){
                    int newBlock = Allocate_FreeBlock();
                    if(newBlock == -1)
                    {
                        printf("磁盘空间不足!写入终止\n");
                        return;
                    }else{
                        int i, j = finode[inode_id].size/(BlockSize + 1);
                        for(i = 0; i < BlockSize - finode[inode_id].size%BlockSize; i++){
                            Disk->data[finode[inode_id].Block[j]][i + finode[inode_id].size%BlockSize] = buf[i];
                        }
                        j++;
                        finode[inode_id].Block[j] = newBlock;
                        for(int k = 0; i < buf_size; i++, k++)
                        {
                            Disk->data[finode[inode_id].Block[j]][k] = buf[i];
                        }
                        finode[inode_id].size += buf_size;
                        buf_size = 0;
                    }
                }else{
                    int i, j = finode[inode_id].size/(BlockSize + 1);
                    for(i = 0; i < buf_size; i++){
                        Disk->data[finode[inode_id].Block[j]][i + finode[inode_id].size%BlockSize] = buf[i];
                    }
                    finode[inode_id].size += buf_size;
                    buf_size = 0;
                }
                maxSize -= buf_size;
            }
        }while(x != 4);
        nowtime = time(0);
		finode[inode_id].fixtime = nowtime;
	}
}

void read(char *name)
{
    int fd = -1;
	for(int i = 0; i < OpenfileNum; i++)
	{
		if(flist_vis[i] && strcmp(name,flist[i].name) == 0)
		{
			fd = i;
			break;
		}
	}
	if(fd == -1){
		printf("该文件未打开\n");
	}else{
	    int inode_id = flist[fd].fnodeID,cnt = 0;
	    printf("——————————————————————————————————————————————————\n");
	    for(int i = 0, j = 0; i < finode[inode_id].size; i++)
        {
        	cnt++;
            if(i == BlockSize){
                j++;
                i = 0;
            }
            printf("%c",Disk->data[finode[inode_id].Block[j]][i]);
        }
        printf("\n——————————————————————————————————————————————————\n");
	}
}

void listshow()
{
	dirFile *dir;
	int current = nodelist[curpoint].Block[0];
	if(current == 1){
		dir = &Disk->root;
	}else{
		dir = (dirFile *)(Disk->data[current]);
	}
	//printf("%d %d\n",current,curpoint);
	printf("——————————————————————————————————————————————————\n\n");
	int file_inode,cnt1 = 0, cnt2 = 0;
	for(int i = 0; i < fcbCount; i++){
		file_inode = dir->list[i].fnodeID;
		if(file_inode != -1)
		{
			if(nodelist[file_inode].format == 2)
			{
				printf("%s          文本文件    %dBytes    ", nodelist[file_inode].name,nodelist[file_inode].size);
				Time_format(nodelist[file_inode].fixtime);
				cnt2++;
			}
			if(nodelist[file_inode].format == 1)
			{
			    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN);
				printf("%s          目录文件    ", nodelist[file_inode].name);
				Time_format(nodelist[file_inode].fixtime);
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
                cnt1++;
			}
		}
	}
	printf("\n此目录共包含文本文件%d个,目录文件%d个\n",cnt2,cnt1);
	printf("——————————————————————————————————————————————————\n");
}

void ShowOpen()
{
	for(int i = 0; i < OpenfileNum; i++)
	{
		if(flist_vis[i])
		{
			printf("%s\n",flist[i].name);
		}
	}
	printf("\n当前已打开%d个文件\n",flist_cnt);
}

void ShowDetails()
{
    dirFile *dir;
	int current = nodelist[curpoint].Block[0];
	if(current == 1){
		dir = &Disk->root;
	}else{
		dir = (dirFile *)(Disk->data[current]);
	}
	printf("——————————————————————————————————————————————————————————————————\n\n");
	printf("文件名||文件大小||文件格式||文件当前inode节点标号||文件上级目录inode节点标号||文件所占用的物理块标号(-1表示未占用)||文件最近修改时间\n");
	for(int i = 0; i < fcbCount; i++){
		int file_inode = dir->list[i].fnodeID;
		if(file_inode != -1)
		{
		    if(nodelist[file_inode].format == 1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			printf("%s||%dByte||%d||%d||%d||%d %d %d %d %d||",nodelist[file_inode].name,nodelist[file_inode].size,nodelist[file_inode].format, nodelist[file_inode].curdir, nodelist[file_inode].fredir, nodelist[file_inode].Block[0], nodelist[file_inode].Block[1], nodelist[file_inode].Block[2], nodelist[file_inode].Block[3], nodelist[file_inode].Block[4]);
			Time_format(nodelist[file_inode].fixtime);
			if(nodelist[file_inode].format == 1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		}
	}
	printf("\n——————————————————————————————————————————————————————————————————\n");
}

void switchDir(char *name)
{
	if(strcmp(name,"..")==0)
	{
		int current = nodelist[curpoint].Block[0];
		if(current == 1){
			printf("已经在根目录中了\n");
		}else{
			int lens = strlen(nodelist[curpoint].name) + 3, lenc = strlen(curPath);
			curPath[lenc - lens - 1] = ':';
			curPath[lenc - lens + 0] = '\\';
			curPath[lenc - lens + 1] = '>';
			curPath[lenc - lens + 2] = '\0';
			curpoint = nodelist[curpoint].fredir;
		}
	}else if(strcmp(name,"/")==0){
        int current = nodelist[curpoint].Block[0];
		while(current != 1){
			int lens = strlen(nodelist[curpoint].name) + 3, lenc = strlen(curPath);
			curPath[lenc - lens - 1] = ':';
			curPath[lenc - lens + 0] = '\\';
			curPath[lenc - lens + 1] = '>';
			curPath[lenc - lens + 2] = '\0';
			curpoint = nodelist[curpoint].fredir;
            current = nodelist[curpoint].Block[0];
		}
    }else{
		int sonpoint = SerchList(name,1);
		if(sonpoint == -1)
		{
			printf("此文件夹下未找到此目录\n");
			return;
		}else{
			curpoint = sonpoint;
			int lens = strlen(name), lenc = strlen(curPath);
			curPath[lenc - 3] = '/';
			for(int i = 0; i < lens; i++)
			{
				curPath[lenc + i - 2] = name[i];
			}
			curPath[lenc + lens - 2] = ':';
			curPath[lenc + lens - 1] = '\\';
			curPath[lenc + lens - 0] = '>';
			curPath[lenc + lens + 1] = '\0';
		}
	}
}

void Time_format(time_t ntime)
{
	char tmp[64];
	struct tm local;
	localtime_s(&local,&ntime);
	strftime(tmp, sizeof(tmp), "%Y/%m/%d %X", &local);
	puts(tmp);
}

void tips()
{
	printf("tips            	:查看操作命令\n");
	printf("format          	:系统格式化\n");
	printf("ls              	:查看当前目录下的文件信息\n");
	printf("lsopen              :查看当前已打开的文件\n");
	printf("lst                 :查看当前目录下的文件的详细信息\n");
	printf("cd     dirname  	:更改目录\n");
	printf("mkdir  dirname  	:创建目录\n");
	printf("rmdir  dirname  	:删除目录\n");
	printf("creat  filename 	:创建文件\n");
	printf("write  filename 	:对已打开的文件进行写入\n");
	printf("read   filename 	:对已打开的文件进行读取\n");
	printf("open   filename 	:打开文件\n");
	printf("close  filename 	:保存文件信息并关闭文件\n");
	printf("rm     filename 	:删除文件\n");
	printf("exit            	:保存并退出系统\n");
	return;
}

void exit()
{
    for(int i = 0; i < OpenfileNum; i++)
	{
		if(flist_vis[i])
		{
			close(flist[i].name);
		}
	}
	memcpy(Disk->_nodelist,nodelist,sizeof(nodelist));
    memcpy(Disk->_nodelist_vis,nodelist_vis,sizeof(nodelist_vis));
    Disk->_inode_cnt = inode_cnt;
	fp = fopen(DiskPath,"w+");
	fwrite(BaseAddr,sizeof(char),sizeof(DISK),fp);
	fclose(fp);
	free(Disk);
	return;
}

void cread(char *name)
{
    int inode_id = SerchList(name,2),cnt = 0;
    printf("——————————————————————————————————————————————————\n");
    for(int i = 0, j = 0; i < nodelist[inode_id].size; i++)
    {
        cnt++;
        if(i == BlockSize){
            j++;
            i = 0;
        }
        printf("%c",Disk->data[nodelist[inode_id].Block[j]][i]);
    }
    printf("\n——————————————————————————————————————————————————\n");
    return;
}

void Copy(char *name)
{
    int id = SerchList(name,2);
    Clipboard.flag = 1;
    Clipboard.cp_inode = nodelist[id];
    return;
}

void Cut(char *name)
{
    int id = SerchList(name,2);
    Clipboard.flag = 2;
    Clipboard.cp_inode = nodelist[id];
    return;
}

void Paste()
{
    if(Clipboard.flag == 0){
        printf("剪切板为空.\n");
        return;
    }else{
        creatfile(Clipboard.cp_inode.name);
        int id = SerchList(Clipboard.cp_inode.name,2);
        for(int i = 0; Clipboard.cp_inode.Block[i] != -1; i++)
        {
            if(nodelist[id].Block[i] == -1)nodelist[id].Block[i] = Allocate_FreeBlock();
            if(nodelist[id].Block[i] == -1){
                printf("磁盘空间不足,粘贴失败\n");
                return;
            }
            for(int j = 0; j < BlockSize; j++)
            {
                Disk->data[nodelist[id].Block[i]][j] =Disk->data[Clipboard.cp_inode.Block[i]][j];
            }
        }
        nodelist[id].size = Clipboard.cp_inode.size;
        if(Clipboard.flag == 2)
        {
            int temp = curpoint;
            curpoint = Clipboard.cp_inode.fredir;
            delfile(Clipboard.cp_inode.name);
            curpoint = temp;
            Clipboard.flag = 0;
        }
    }
    return;
}

int main()
{
    char opt[20];
    char name[20];
    char password[40];
	printf("----------A Simple Virtual FileOS----------\n");
	printf("\n");
	printf("登录(login)\n");
	printf("注册(register)\n");
	printf("\n");
	BaseAddr = (char *)malloc(sizeof (DISK));
	Disk = (DISK *)(BaseAddr);
    while(1){
        scanf("%s",opt);
        if(strcmp(opt,"Register")==0 || strcmp(opt,"register")==0){
            printf("请输入用户名:\n");
            scanf("%s",name);
            printf("请输入密码:\n");
            scanf("%s",password);
            strcat(DiskPath,name);
            printf("%s\n",DiskPath);
            if((fp = fopen(DiskPath,"r"))!= NULL)
            {
                printf("该用户名已被注册\n");
                strcpy(DiskPath,"D://mytest//");
            }else{
                fread(BaseAddr,sizeof(char),sizeof(DISK),fp);
                strcpy(Disk->Password,password);
                printf("首次使用此系统,正在进行初始化...\n");
                format();
                printf("初始化完成,可以进行操作了!\n");
                break;
            }
        }else if(strcmp(opt,"Login")==0 || strcmp(opt,"login")==0){
            printf("请输入用户名:\n");
            scanf("%s",name);
            printf("请输入密码:\n");
            scanf("%s",password);
            strcat(DiskPath,name);
            if((fp = fopen(DiskPath,"r"))!=NULL)
            {
                fread(BaseAddr,sizeof(char),sizeof(DISK),fp);
                if(strcmp(Disk->Password,password) == 0){
                    printf("加载中...\n");
                    reload();
//                    for(int i = 0; i < BlockNum; i++){
//                        printf("%d ",nodelist_vis[i]);
//                    }
                    printf("已装载磁盘(%s),可以继续操作.\n",DiskPath);
                    break;
                }else{
                    printf("用户名或密码错误\n");
                    strcpy(DiskPath,"D://mytest//");
                }
            }else{
                printf("该用户不存在\n");
                strcpy(DiskPath,"D://mytest//");
            }
        }else{
            printf("请先完成登录或注册\n");
        }
    }
    tips();
    printf("\n");
    while(1){
        printf("%s",curPath);
        scanf("%s",opt);
        if(strcmp(opt,"tips")==0){
            tips();
        }else if(strcmp(opt,"format")==0){
            format();
        }else if(strcmp(opt,"ls")==0){
            listshow();
        }else if(strcmp(opt,"cd")==0){
            scanf("%s",name);
            switchDir(name);
        }else if(strcmp(opt,"mkdir")==0){
            scanf("%s",name);
            mkdir(name);
        }else if(strcmp(opt,"rmdir")==0){
            scanf("%s",name);
            rmdir(name);
        }else if(strcmp(opt,"creat")==0){
            scanf("%s",name);
            creatfile(name);
        }else if(strcmp(opt,"rm")==0){
            scanf("%s",name);
            delfile(name);
        }else if(strcmp(opt,"exit")==0){
        	exit();
            break;
        }else if(strcmp(opt,"open")==0){
        	scanf("%s",name);
        	openf(name);
        }else if(strcmp(opt,"close")==0){
        	scanf("%s",name);
        	close(name);
        }else if(strcmp(opt,"write")==0){
        	scanf("%s",name);
        	getchar();
        	write(name);
        }else if(strcmp(opt,"read")==0){
        	scanf("%s",name);
        	read(name);
        }else if(strcmp(opt,"lsopen")==0){
        	ShowOpen();
        }else if(strcmp(opt,"lst")==0){
        	ShowDetails();
        }else if(strcmp(opt,"cat")==0){
            scanf("%s",name);
            cread(name);
        }else if(strcmp(opt,"copy")==0){
            scanf("%s",name);
            Copy(name);
        }else if(strcmp(opt,"cut")==0){
            scanf("%s",name);
            Cut(name);
        }else if(strcmp(opt,"paste")==0){
            Paste();
        }else{
            printf("指令错误,%s不是一个系统指令\n",opt);
        }
    }
	return 0;
}

 

模拟Linux文件系统。在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的 模拟Linux文件系统 在现有机器硬盘上开辟20M的硬盘空间,作为设定的硬盘空间。 2. 编写一管理程序对此空间进行管理,以模拟Linux文件系统,具体要求如下: (1) 要求盘块大小1k 正规文件 (2) i 结点文件类型 目录文件 (共1byte) 块设备 管道文件 物理地址(索引表) 共有13个表项,每表项2byte 文件长度 4byte 。联结计数 1byte (3)0号块 超级块 栈长度50 空闲盘块的管理:成组链接 ( UNIX) 位示图 (Linux) (4)每建一个目录,分配4个物理块 文件名 14byte (5)目录项信息 i 结点号 2byte (6)结构: 0#: 超级块 1#-20#号为 i 结点区 20#-30#号为根目录区 3. 该管理程序的功能要求如下: (1) 能够显示整个系统信息,源文件可以进行读写保护。目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开。 (2) 改变目录:改变当前工作目录,目录不存在时给出出错信息。 (3) 显示目录:显示指定目录下或当前目录下的信息,包括文件名、物理地址、保护码、文件长度、子目录等(带/s参数的dir命令,显示所有子目录)。 (4) 创建目录:在指定路径或当前路径下创建指定目录。重名时给出错信息。 (5) 删除目录:删除指定目录下所有文件和子目录。要删目录不空时,要给出提示是否要删除。 (6) 建立文件(需给出文件名,文件长度)。 (7) 打开文件(显示文件所占的盘块)。 (8) 删除文件:删除指定文件,不存在时给出出错信息。 4. 程序的总体流程为: (1) 初始化文件目录; (2) 输出提示符,等待接受命令,分析键入的命令; (3) 对合的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令,直到键入EXIT退出为止。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值