如何用C/C++写一个Linux文件系统模拟器_string homepath("c:\\users\\seanwayen\\desktop\\ho-程序员宅基地

技术标签: 虚拟机  c++  Linux  linux  操作系统  windows  unix  

1. 程序演示

在这里插入图片描述
home目录下包含如下文件
在这里插入图片描述

其中root文件夹内存有account.txt,用于存储用户登录信息,在虚拟磁盘初始化时将之读入用户组结构并用于验证登录。
在这里插入图片描述
运行程序:
在这里插入图片描述

1. 登录–login

运行程序后只能先登录才能进行操作,不然会系统提示进行登录,输入help可以查看命令帮助文件。
在这里插入图片描述

2. 切换目录— cd

3. 展示文件列表—ls

在这里插入图片描述
对应本地真实目录可知,初始化成功,目录树建立成功,且各个文件/文件夹的大小、路径、文件类型、读写权限、所属用户都初始化成功!
在这里插入图片描述
在这里插入图片描述

4. 查看物理块使用情况以及物理块存储内容 — df

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
df命令中展示了已占用物理块的存储内容:
(1)complete file of xxx : 表明该物理块存储了一个完整的文件
(2)parts of xxx: 表明该物理块存储了一个文件的部分内容
(3)IndexBlock of xxx: 表明该物理块为索引物理块
可见初始化时占用物理块为462块,大约占用了虚拟磁盘462KB的空间,由于在该虚拟磁盘中文件夹都单独占用一个索引物理块,且所有的索引物理块不存储具体文件内容,故其空间开支稍大于实际空间开支,可由比较本地实际目录大小(436KB)可证明。
在这里插入图片描述

5. cd命令的延伸 :

(1)cd ./ :返回当前目录
(2)cd …/ :返回上一级目录
(3)cd home :返回用户根目录

6. 查看当前目录名和父目录名 —— now

在这里插入图片描述

7. 创建文件—— touch

在这里插入图片描述
同时在本地文件中也进行了创建文件的操作
在这里插入图片描述

8. 打开文件 —— open

9. 查看当前活动文件 —— ASL

在这里插入图片描述
若输入的文件名不正确会有相应提示。

10. 写文件操作 —— write

(1) write -a 追加写入文件
(2) write -c 覆盖写入文件
在这里插入图片描述
若是没有将文件打开就要写入则会提示先将文件打开;
在这里插入图片描述
成功写入。

注意在写入文件后,文件的大小以及所属父目录的大小都得到更新。
在这里插入图片描述

11. 读文件的全部内容 —— cat

在这里插入图片描述
若没有将文件打开就进行读操作则会进行提示。
在这里插入图片描述

下面读取inode.txt为例,由于文件较长,只截取开头和结尾部分(inode.txt为编写该项目的过程中留下的一份备份txt文件):
在这里插入图片描述
在这里插入图片描述

12. head -num 读取文件头num行

13. tail -num 读取头文件num行

在这里插入图片描述

14. 关闭文件 —— close

在这里插入图片描述

15. 递归查找文件 —— find

在这里插入图片描述

16. 复制文件 —— cp

在这里插入图片描述
本地文件夹同步实现了复制操作
在这里插入图片描述
而且物理块也实现了相应的变化,增加了新文件占用的物理块:
在这里插入图片描述

17. 移动文件 —— move

在这里插入图片描述

在这里插入图片描述

18. 创建文件夹 —— mkdir

在这里插入图片描述

19. 删除文件夹 —— rm -rf

在新建的OSmenu文件夹中新建两个文件(一个创建,一个通过复制创建)后进行删除
在这里插入图片描述
在这里插入图片描述
本地文件夹中也同步了操作

下面进行删除,可以将文件夹以及其中的文件都删掉
在这里插入图片描述
文件夹也同步了该操作
在这里插入图片描述

20. 删除文件 —— rm -f

在这里插入图片描述
本地文件夹也同步了相应操作
在这里插入图片描述


2. 代码部分

2.1 本项目使用的结构体

代码中使用到的结构体信息如下:

2.1.1 用户结构

用户结构体中包含用户的用户名和密码,以及该用户的个人根目录。

`typedef struct User_Type
{
string username;//用户名
string password;//密码
struct FSct_Type *userFile;//指向该用户的"根"目录
}User;

2.1.2 文件控制块

该文件控制块结构在文件结构中的集合构成了文件目录。

typedef struct FCB{
User *Owner[12];//指向用户数据结构User的指针
int innerNum; //内部号
string fileName; //文件名
string type; // 文件类型
double length; //文件长度
long int authority; //读写权限
int phNum; //物理块号
struct PHB_Type *firstBlock; //首物理块
}FCB;

2.1.3 文件结构

文件结构中包含了以下信息:
(1)文件的名称;
(2)文件的路径;
(3)文件的所属用户组(考虑到可以实现文件共享);
(4)以及该目录下的文件目录表(由12个文件控制块组成,即限制了每个文件夹最多放置12个文件);
(5)文件内容(由于文件类型较多,此处的文件内容暂时用”parts of xxx”等来替代);
(6)子文件/子目录指针(与文件控制块fcb相对应,共12个);
(7)父目录指针(只有一个);

typedef struct FSct_Type{
string fileName;
string filePath;
User *Owner[12]; //用户账号
FCB *fcb[12]; //文件目录
char content[50]; //文件内容
struct FSct_Type *child[12]; //指针数组,指向二级文件结构
struct FSct_Type *pre; //指针,指向父目录
}FSct;

2.1.4 物理块结构

物理块结构包含了以下信息:
(1)物理块号;
(2)每个物理块的大小:该项目规定每个物理块的大小为1024B,即1KB;
(3)物理块状态标识符,空闲状态为0,占用状态为0;
(4)物理块索引表:当所存储的文件大小大于1KB时,其首物理块存储一个物理块索引表;
(5)索引指针:当所存储的文件大小大于1KB时,指向其他实际存储文件信息的物理块;
(8)物理块所存内容:由于文件类型较多,并不一定都可按字符读出保存到虚拟磁盘,此处的文件内容暂时用”parts/complete/index of xxx”等来替代。

typedef struct PHB_Type{
long int phNum; //物理块号
long int chunckSize = 1024; //每个块大小为1024B 即1KB
int state = 0; //物理块状态标识符
long int indexList[300]; //该块所保存的索引表
struct PHB_Type *child[300]; //索引表指向的块
string content;//该块所保存的内容
}PHB;

2.1.5 活动符号名表

活动符号名表用于存储打开文件的信息,该结构包含以下信息:
(1)文件名;
(2)对应文件控制块的内部号;
(3)文件路径(便于区分不同目录下的同名文件);
(4)指向活动文件表的指针。

typedef struct Active_symbol_list{
string fileName;
int innerNum;//内部号
string path;//文件路径
struct Active_file_list *afl;
struct Active_symbol_list *next;
}ASL;

2.1.6活动文件表
活动文件表用于存储文件目录的及本条目,即文件控制块。

typedef struct Active_file_list{
FCB *fcb;//由基本文件目录项(FCB块)组成的数组
struct Active_file_list *next;
}AFL;

2.2 完整代码

#include <pthread.h>
#define NUM_THREADS 1 //多线程并发数 
#include <iostream>
#include<fstream>  
#include<string>
#include<cstring>
#include<iomanip>
#include <malloc.h>
#include <vector>
#include <io.h>
#include <Windows.h>  
#include <sys\stat.h>
using namespace std;
#define BUFFER_SIZE 

string homePath("C:\\Users\\SeanWayen\\Desktop\\home");
string path("C:\\Users\\SeanWayen\\Desktop\\home"); 
string tmpPath = homePath;

//用户数据结构
typedef struct User_Type
{
    
	string username;//用户名
	string password;//密码
	struct FSct_Type *userFile;//指向该用户的"根"目录 ,即在注册或从文件导入数据生成一个 用户时要给用户指向一个文件 
}User;

 //文件控制块 
typedef struct FCB{
    
	User *Owner[12];//指向用户数据结构User的指针 
	int innerNum;//内部号 
	string fileName;//文件名 
	string type;// 文件类型 
	double length;//文件长度 
	long int authority;//读写权限 
	int phNum; //物理块号 
	struct PHB_Type *firstBlock; 
}FCB;

//文件结构 
typedef struct FSct_Type{
    
	int i;
	string fileName;
	string filePath; 
	User *Owner[12];//用户账号 
	FCB *fcb[12]; //文件目录 
	char content[50];//文件内容 (待处理) 
	struct FSct_Type *child[12];//指针数组,指向二级文件结构 
	struct FSct_Type *parent;//指针,指向父目录 
	struct FSct_Type *pre;//指针,指向父目录 
}FSct;

//物理块结构
typedef struct PHB_Type{
    
	long int phNum;//物理块号 (在程序初始化时要自动生成) 
	long int chunckSize = 1024;//每个块大小为1024B 即1KB
	int state = 0;//初始化时 所有块都为0表示空闲,被占用时状态为1 
	long int indexList[300];//该块所保存的索引表 
	struct PHB_Type *child[30];//索引表指向的块 
	string content;//该块所保存的内容 
}PHB; 


//活动符号名表 
typedef struct Active_symbol_list{
    
	string fileName;
	int innerNum;//内部号 
	string path;//文件路径 
	struct Active_file_list *afl;
	struct Active_symbol_list *next;
}ASL;

//活动文件表 
typedef struct Active_file_list{
    
	FCB *fcb;//由基本文件目录项(FCB块)组成的数组 
	struct Active_file_list *next;
}AFL; 




PHB phBlock[1024*1024];//一共2^20个block,每个block大小为1KB,虚拟磁盘共1GB 
User uGroup[12];//用户组数组,后期要将文件中的用户读入 
FSct *UserFile[12];//12个用户对应12个用户根目录 
//FSct *home = (FSct *)malloc(sizeof(FSct));//home目录 
FSct *home = new FSct;
string userPath[12];
ASL *Shead = new ASL;//活动符号名表  表头 
AFL *Fhead = new AFL;//活动文件表   表头 
int FileNum_Curr = 0; //当前文件数目 

//引导函数
void help(){
    
	cout <<endl; 
	cout << "*******************欢迎使用多级文件系统*******************" << endl<<endl;
	cout << "        命令                    说明                      " << endl;
	cout << "        login                   登录                      " << endl;
	cout << "        cd                      更改当前目录              " << endl;
	cout << "        ls                      展示文件列表              " << endl;
	cout << "        touch                   创建文件                  " << endl;
	cout << "        rm -f                   删除文件                  " << endl;
	cout << "        mkdir                   创建目录                  " << endl;
	cout << "        rm -rf                  递归地删除目录及其文件    " << endl;
	cout << "        open                    打开文件                  " << endl;		
	cout << "        close                   关闭文件                  " << endl;
	cout << "        cat                     读文件到控制台            " << endl;		
	cout << "        tail -num               显示文件尾num行           " << endl;
	cout << "        head -num               显示文件头num行           " << endl;
	cout << "        write -c                写入文件(覆盖)          " << endl;
	cout << "        write -a                写入文件(追加)          " << endl;		
	cout << "        find                    递归地查找文件            " << endl;
	cout << "        cp                      复制文件                  " << endl;
	cout << "        move                    移动文件                  " << endl;
	cout << "        export                  导出文件                  " << endl;
	cout << "        import                  导入文件                  " << endl<<endl;
	cout << "*******************欢迎使用多级文件系统*******************" << endl;
	cout <<endl;
} 


//查看用户组 
void check_uGroup(){
    
	cout<<"——————————" <<endl<<"查看用户组"<<endl;
	for(int i=0; i<sizeof(uGroup); i++){
    
	    if(uGroup[i].username.length()!=0){
    
	       	cout<<"uGroup["<<i<<"]:"<<endl;
	       	cout<<"username:"<<uGroup[i].username<<endl;
	       	cout<<"password:"<<uGroup[i].password<<endl;
			}else{
    
			 	break;
			}
	   	}
	cout<<"——————————" <<endl;
}

//查看物理块使用情况 
void check_phBlock(){
    
	cout<<"——————————" <<endl<<"查看物理块使用情况"<<endl;
	double Use = 0.0;
	double NotUse = 0.0;
	double UsingRate;
	cout<<"已被使用的物理块号:"<<endl; 
	for(long int i=0; i<1024*1024; i++){
    
	    if(phBlock[i].state==1){
    
	       	cout<<i<<"|";
	       	Use++;
		 }else{
    
			NotUse++;
			}
	}
	UsingRate = Use/(Use+NotUse);
	
	cout<<endl<<"已使用物理块数目:"<<Use<<endl;
	cout<<"空闲物理块数目:"<<NotUse<<endl; 
	cout<<"物理块总数:"<<Use+NotUse<<endl; 
	cout<<"磁盘利用率:"<< UsingRate<<endl;
	cout<<"——————————" <<endl;
}

//读取用户组uGroup信息 

int account(string path){
    
    ifstream in(path);
    string line;
    int i=0;
 
    if(in) // 有该文件
       while (getline (in, line)){
    
       	string info = line;
       	string ID = info.substr(0,info.find_first_of(","));
       	string PW = info.substr(info.find_first_of(",")+1,info.length());
       	uGroup[i].username = ID;
       	uGroup[i].password = PW;
       	//cout<<"账号:"<<uGroup[i].username<<endl<<"密码:"<<uGroup[i].password<<endl; 
       	i++;
       	//cout<< line <<endl;
	   }  
       
        
    else // 没有该文件
       cout <<"no such file" << endl;
       
    in.close();

    return i; 
}


int index(){
    
	int num = -1;
	int flag= 0;
	
	
while(num == -1){
    
	
	cout<<"localhost: " ;
	string tmpOrder;
	cin>>tmpOrder;
	
	//登录界面 
	if(tmpOrder == "login"){
    
		cout<<"user: ";
		string ID;
		cin>>ID;
		
		cout<<"passwords: ";
		string PW;
		cin>>PW;
		
		for(int i=0;i<sizeof(uGroup);i++){
    
			if(uGroup[i].username == ID && uGroup[i].password == PW){
    
				num = i;
				flag =1 ;
				break;
			}
		}
	}
	
	else if(tmpOrder == "help"){
    
		help();
	}
	
	else{
    
		cout<<"please login first !"<<endl;
	}
}
	
	
	if(flag == 0){
    
		cout<<"No such account!"<<endl; 
		return -1;
	} 
	
	else if(flag == 1){
    
		cout<<"Login succed !"<<endl;
		return num;
	}
}



int REGISTER()//(1)向用户组增添新成员 (2)初始化该用户的文件目录  //目前相当于初始化 
{
    

	cout << "请输入用户名:";
	string userName;
	cin >> userName;
	cout << "请输入密码:";
	string passWord;
	cin >> passWord;
	

	for(int i=0; i<sizeof(uGroup); i++){
    
		
		if (uGroup[i].username == userName)
		{
    
			cout<<i<<endl;
			cout<< uGroup[i].username<<endl;
			
			cout << "注册失败,该用户名已存在" << endl;
			break;
		}
		if(uGroup[i].username.length()==0){
    
	
			uGroup[i].username = userName;
	        uGroup[i].password = passWord;
	        cout << "注册成功" << endl;
	        
	        home->fcb[i] = new FCB;
	        home->fcb[i]->innerNum = i;
	        home->fcb[i]->fileName = uGroup[i].username;//强制命名为用户名,用户无权限修改该名称
			home->fcb[i]->authority = 666;//默认新建目录权限
			home->fcb[i]->type = "dir";//文件类型为目录 
			home->fcb[i]->phNum = i;// 假设一级目录 默认块号 为i,物理块i中存储一个索引表; 
			
			home->fcb[i]->firstBlock = new PHB;//将该FCB指向其首物理块
			home->fcb[i]->firstBlock->state = 1; //表示此块已被占用 
			home->fcb[i]->firstBlock->phNum = i;//物理块内部标识的物理块号
			phBlock[i]. state = 1;  //在物理外存上进行标识,方便为新文件分配空间 
			phBlock[i].content = "用户根目录"+i; 
			 
			home->child[i] = new FSct;
			home->child[i]->fileName = uGroup[i].username;
			home->child[i]->Owner[0] = new User;//为用户文件中的结构体指针开辟空间 
            home->child[i]->Owner[0]->username=uGroup[i].username;
	        break;  
		}
	}
	return 1;
}



//获取文件大小 
double get_length(string filePath){
    
	double sizeKB = 0;
			
	ifstream fin( filePath );
	if( fin.is_open() )
	{
    
	    fin.seekg( 0, ios::end );
        double size = fin.tellg();
        if(size == 0){
    
		    sizeKB = 0;
		}else{
    
			sizeKB = size/1024;
		}
		fin.close();
	}
	return sizeKB; 
}

//递归计算文件夹大小 
double getDirSize(string path)//获取path下所有文件的名称 ,包含递归查询所有的子目录下的文件 ,但不包含目录 
{
    
	//文件句柄
	intptr_t hFile = 0;
	vector<string> files; 
	
	//文件信息
	struct _finddata_t fileinfo;
	string p;
	double filesize;
	int i = 0;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
    
		do
		{
    
		
			if ((fileinfo.attrib & _A_SUBDIR))//判断是否是文件夹 
			{
    
				//如果是目录,递归查找
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0){
    
					filesize +=getDirSize(p.assign(path).append("\\").append(fileinfo.name));
				}
					
			}
			else
			{
    
				//如果不是,把文件绝对路径存入vector中
				filesize += get_length(path+"\\"+fileinfo.name);
			}
			
			
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	}
	
	return filesize; 
}

//给一级目录的文件长度赋值 
void Give_Length(){
    

	string path("C:\\Users\\SeanWayen\\Desktop\\home"); 
	intptr_t hFile = 0;
	struct _finddata_t fileinfo;
	string p;
	int i=0;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
    
		
		do
		{
    
			if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
			{
    
				string filePath(path+"\\"+fileinfo.name);
				
				if ((fileinfo.attrib & _A_SUBDIR))//是文件夹 
				{
    
					double sizeKB = getDirSize(filePath); //递归计算文件夹大小 
					home->fcb[i]->length = sizeKB;
			        i++ ;  	
				}
				
				else
				{
    
					double sizeKB = get_length(filePath);
			        home->fcb[i]->length = sizeKB;
			        i++ ;  	
				}

	    }

		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
		//cout<<endl;
	}
}


	
	
void ls_alh(){
    //详细展示文件信息,待修改的问题还有两个:(1)KB和MB和GB的单位需要写一个switch/if-elseif转换  (2)文件夹的大小返回值仍为0,还需递归计算文件夹大小 
	int j=0;
	while(home->fcb[j]){
    
		//cout<<i<<endl; 
		cout<<home->fcb[j]->type<<'\t'<<home->fcb[j]->authority<<"\t"<<home->fcb[j]->fileName<<"\t";
		if(home->fcb[j]->length < 512 && home->fcb[j]->length > 0.01){
    
			cout<<setprecision(3)<< home->fcb[j]->length<<"KB"<<"\t";
		}else if(home->fcb[j]->length > 512){
    
			cout<<setprecision(3)<< (home->fcb[j]->length)/1024 <<"MB"<<"\t";//如果文件大于1024KB则按照MB单位输出 
		}else if(home->fcb[j]->length < 0.01){
    
			cout<<setprecision(3)<< (home->fcb[j]->length)*1024 <<"B"<<"\t";//如果文件大于1024KB则按照MB单位输出 
		}
		cout<<home->fcb[j]->fileName<<'\t'<<endl;
		j++;
	}
}




string ID_path = "C:\\Users\\SeanWayen\\Desktop\\home\\root\\account.txt";

//一级目录(用户目录)初始化(每个文件夹占一个物理块,该物理块内部存储文件夹中内容列表) 
void Initial(string path){
    
	
	//先读入用户组信息
	int userNum = account(ID_path); 
	
	Shead->next = NULL;
	Fhead->next =NULL;
	

	vector<string> fileNames;
	cout<<"初始化... "<<endl;
	
	//文件句柄
	intptr_t hFile = 0;
	int key = 0;
	//文件信息
	struct _finddata_t fileinfo;
	string p;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
    
		do
		{
    
			if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0){
    
				
				userPath[key]=(path+"\\"+fileinfo.name);
				key++;
			   // cout<<fileinfo.name<<"   ";
	            for(int i=0; i<sizeof(uGroup); i++){
    
	            	if(uGroup[i].username == fileinfo.name){
    
						home->fcb[i] = new FCB;
						home->fcb[i]->innerNum = i;
						home->fcb[i]->fileName = uGroup[i].username;//强制命名为用户名,用户无权限修改该名称
						home->fcb[i]->authority = 666;//默认新建目录权限
						if ((fileinfo.attrib & _A_SUBDIR)){
    
						   home->fcb[i]->type = "dir";//文件类型为目录 
						}else{
    
						   home->fcb[i]->type ="—";//可以分的更细致 
						}
						
						home->fcb[i]->phNum = i;// 假设一级目录 默认块号 为i,物理块i中存储一个索引表; 
						home->fcb[i]->Owner[0]=new User;
						home->fcb[i]->Owner[0]->username=uGroup[i].username;
			
			            //开辟物理块 
			            home->fcb[i]->firstBlock = new PHB;//将该FCB指向其首物理块
			            home->fcb[i]->firstBlock->state = 1; //表示此块已被占用 
			            home->fcb[i]->firstBlock->phNum = i;//物理块内部标识的物理块号
			            phBlock[i]. state = 1;  //在物理外存上进行标识,方便为新文件分配空间 
			            phBlock[i].content = ("User Directory: "+home->fcb[i]->fileName); 
			 
	       
			            home->child[i] = new FSct;
			           // home->child[i]->parent = home;
			            home->child[i]->fileName = fileinfo.name;
			            home->child[i]->filePath = (path+"\\"+fileinfo.name);
			            home->child[i]->Owner[0] = new User;//为用户文件中的结构体指针开辟空间 
			            home->child[i]->Owner[0]->username=uGroup[i].username;
			            break;  
			        }
            	}			
		    }	
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
		//cout<<endl;
	}
	Give_Length(); 
}




//给二级目录的文件下所有文件长度赋值 (递归)
void Give_Length_Sec_ByTree(string path,FSct *tmpFile){
    

	intptr_t hFile = 0;
	struct _finddata_t fileinfo;
	string p;
	int i=0;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
    
		
		do
		{
    
			if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
			{
    
				string filePath(path+"\\"+fileinfo.name);
				
				if ((fileinfo.attrib & _A_SUBDIR))//是文件夹 
				{
    
					
					double sizeKB = getDirSize(filePath); //递归计算文件夹大小 
					tmpFile->fcb[i]->length = sizeKB; 
			        i++ ; 
				}
				
				else
				{
    
					double sizeKB = get_length(filePath);
			        tmpFile->fcb[i]->length = sizeKB;
			        i++ ;  	
				}
	    }

		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	//	cout<<endl;
	}
}





//给二级文件系统(用户目录系统)下 的文件分配物理块 (递归) 
void setBlock_ByTree(FSct *tmpFile){
    
for(int i = 0; i<12;i++){
    
		
	if(tmpFile->fcb[i] != NULL){
    
			
		if(tmpFile->fcb[i]->type == "—"){
    
			if(tmpFile->fcb[i]->length < 1)
			{
    
				tmpFile->fcb[i]->firstBlock->content = ("complete file of "+tmpFile->fcb[i]->fileName);
				long int phNum = tmpFile->fcb[i]->firstBlock->phNum;//注意一下动态分配数组已限定一个文件的最大大小
				string tmpContent = ("complete of "+tmpFile->fcb[i]->fileName);
				phBlock[phNum].content =tmpContent;
			}
			
			else if(tmpFile->fcb[i]->length > 1)
			{
    
				//先处理在初始化就分配好的块 
				tmpFile->fcb[i]->firstBlock->content = ("IndexBlock of "+tmpFile->fcb[i]->fileName);
				long int phNum = tmpFile->fcb[i]->firstBlock->phNum;//注意一下动态分配数组已限定一个文件的最大大小
				phBlock[phNum].content = ("IndexBlock of "+tmpFile->fcb[i]->fileName);
				
				
				int count = tmpFile->fcb[i]->length/1.0;
				if(tmpFile->fcb[i]->length > count+0.5) count++;//count为实际要为该文件分配的块数 
				
				
				int tmpNum = 0;
				for(long int num=0;num < 1024*1024; num++){
    
					if(phBlock[num].state==0 && tmpNum<=count){
    
						phBlock[num].state = 1;
						string tmpContent = ("Parts file of "+tmpFile->fcb[i]->fileName);
						phBlock[num].content = tmpContent;
						
						int first = tmpFile->fcb[i]->firstBlock->phNum;
						phBlock[first].indexList[tmpNum] = num; //还要处理动态分配数组 
						tmpNum++;
					}
					if(tmpNum == count) break;
				}
				
			}
	   }
	    
	    
	    else if(tmpFile->fcb[i]->type == "dir") {
    
	    	tmpFile->fcb[i]->firstBlock->content = ("DirBlock of "+tmpFile->fcb[i]->fileName);
			long int phNum = tmpFile->fcb[i]->firstBlock->phNum;//这里的firstBlock在初始化的时候已经分配了 
			string tmpContent = ("DirBlock of"+tmpFile->fcb[i]->fileName);
			phBlock[phNum].content =tmpContent;
	    //	tmpFile->child[i] = new FSct;//在初始化的时候这个结点就已经开辟了 
	    	
	    	//递归分配物理块 
	    //	setBlock_ByTree(tmpFile->child[i]); //这不用递归!!!因为递归的出口是文件而不是文件夹!在初始化中进行一次递归即可!!! 
		}
	}
  }
}

//二级目录初始化(每个文件夹占一个物理块,该物理块内部存储文件夹中内容列表) (递归) 
void Initial_Sec_ByTree(string path, FSct *TMPFILE, FSct *parentFile, int key){
    

	vector<string> fileNames;
	//cout<<"初始化"+path+"下包括目录的所有文件结构 "<<endl;
	
	//文件句柄
	intptr_t hFile = 0;
	
	//文件信息
	struct _finddata_t fileinfo;
	string p;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
    
		do
		{
    
			if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0){
    
	            for(int i=0; i<12; i++){
     //12是一个文件夹中文件的最大限制 
	            	if(TMPFILE->fcb[i] == NULL){
    
	            		FSct *tmpFile = new FSct;
	            		tmpFile = TMPFILE;//在每个循环中new一个新结点,相当于复位,但是空间开支多了 
	            		tmpFile->child[i] = new FSct;
	            		tmpFile->child[i]->fileName = fileinfo.name;
	            		tmpFile->child[i]->filePath = (path+"\\"+tmpFile->child[i]->fileName);
	            	

						tmpFile->fcb[i] = new FCB;
						tmpFile->fcb[i]->innerNum = i;
						tmpFile->fcb[i]->fileName = fileinfo.name;
						tmpFile->fcb[i]->authority = 666;//默认新建目录权限
						
						if ((fileinfo.attrib & _A_SUBDIR)){
      //要对此处做递归初始化 
						   tmpFile->fcb[i]->type = "dir";//文件类型为目录 
						}else{
    
						   tmpFile->fcb[i]->type ="—";//可以分的更细致 
						}
						
						
						//处理物理块的分配 
						for(long int num=0;num<1024*1024;num++){
    // 需要去找一个空闲块号 
							if(phBlock[num].state == 0 ){
    
								//cout<<num<<endl; 
								tmpFile->fcb[i]->phNum = num;
								phBlock[num].state = 1;
							//	cout<<"初始化成功,(首)物理块号为:"<<tmpFile->fcb[i]->phNum<<"  ";
							//	cout<<"文件类型:"<<tmpFile->fcb[i]->type<<endl; 
								
								
								//开辟物理块 
			                    tmpFile->fcb[i]->firstBlock = new PHB;//将该FCB指向其首物理块
			                    tmpFile->fcb[i]->firstBlock->state = 1; //表示此块已被占用 
			                    tmpFile->fcb[i]->firstBlock->phNum = num;//物理块内部标识的物理块号
			                    break; //注意这个break要写在if语句的里面 
							} 
						}
						 
					
						tmpFile->fcb[i]->Owner[0]=new User;
						tmpFile->fcb[i]->Owner[0]->username = uGroup[key].username;
						
						if(tmpFile->fcb[i]->type == "dir" ){
    //如果是文件,递归初始化一下 
							//tmpFile->child[i]->parent = tmpFile;
							FSct *newFile = new FSct;
							newFile = tmpFile->child[i];
							Initial_Sec_ByTree((path+"\\"+fileinfo.name),newFile,tmpFile,key);
						}
						break;  
			        }
            	}			
		    }	
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
		//cout<<endl;
	}
	
	Give_Length_Sec_ByTree(path,TMPFILE);
	setBlock_ByTree(TMPFILE); 
	
	
}



//二级文件 的ls-alh 
void ls_alh_ByTree(FSct *tmpFile){
    //详细展示文件信息  key是home->child[key]中的索引 

	for(int j=0;j<12;j++){
    
		
	  if(tmpFile->fcb[j]){
    
	
 
		cout<<tmpFile->fcb[j]->type<<'\t'<<tmpFile->fcb[j]->authority<<"\t"<<tmpFile->fcb[j]->Owner[0]->username<<"\t";
		if(tmpFile->fcb[j]->length < 512 && tmpFile->fcb[j]->length > 0.01){
    
			cout<<setprecision(3)<< tmpFile->fcb[j]->length<<"KB"<<"\t";
		}else if(tmpFile->fcb[j]->length > 512){
    
			cout<<setprecision(3)<< (tmpFile->fcb[j]->length)/1024 <<"MB"<<"\t";//如果文件大于1024KB则按照MB单位输出 
		}else if(tmpFile->fcb[j]->length < 0.01){
    
			cout<<setprecision(3)<< (tmpFile->fcb[j]->length)*1024 <<"B"<<"\t";//如果文件大于1024KB则按照MB单位输出 
		}
		cout<<tmpFile->fcb[j]->fileName<<'\t'<<tmpFile->child[j]->filePath<<endl;
	}
	}
	cout<<"————————————————————————————————————"<<endl; 
}

void setParent_ByTree(FSct *tmpPath){
    
		
	for(int i=0;i<12;i++){
    
		if(tmpPath->fcb[i]){
    
			
			if(tmpPath->fcb[i]->type == "dir"){
    
				setParent_ByTree(tmpPath->child[i]);
			}
			tmpPath->child[i]->pre=tmpPath; 
		}
	}
}

void setParent(){
    
		
	for(int i=0;i<12;i++){
    
		if(home->fcb[i]){
    
			home->child[i]->pre=home; 
		}
	}
}



void Initial_Sec_All(){
    
	cout<<"构建目录结构树并分配物理块..."<<endl;
	for(int key=0;key<12;key++){
    
		if(!userPath[key].empty()){
    
			FSct *tmpFile = new FSct;
			tmpFile = home->child[key];
			Initial_Sec_ByTree(userPath[key],tmpFile,home,key);
			//ls_alh_ByTree(tmpFile);
		}
	}
	cout<<"初始化成功!请先登录!输入help可查看命令帮助文本..."<<endl; 
}

void check_Block_Content(){
    
	for(long int i=0;i<1024*1024; i++){
    
		if(phBlock[i].state == 1){
    
			cout<<"物理块"<<i<<"存储的内容:"<<phBlock[i].content<<endl; 
		}
	}
}


	

void walkAll(FSct *tmpFile){
    
	cout<<"*****************************************************************"<<endl;
	
	for(int i=0;i<12;i++){
    
		if(tmpFile->fcb[i]){
    
			ls_alh_ByTree(home->child[i]);
		}
	}
	
	cout<<"*****************************************************************"<<endl;
	//一些具有代表性的测试样例 
	/*
	cout<<home->child[0]->child[0]->fileName<<endl;
	cout<<home->child[2]->child[0]->child[0]->pre->fileName<<endl;
	cout<<home->child[2]->child[0]->child[0]->child[0]->pre->fileName<<endl;
	cout<<home->child[2]->child[0]->child[0]->child[0]->fileName<<endl;
	*/
	cout<<"*****************************************************************"<<endl;
	
}


//创建文档文件函数 
void create_txt(string path){
      
  ofstream File;
  char *tmp = &path[0];
  File.open(tmp);
  File.close();
}


//对一个文件(非目录)的简单非递归删除 
void rm_f(string realFilePath,FSct *tmpF,int i){
    
	//在这里做删除操作,要注意(1)根据其长度释放其firstBlock中的indexList中的物理块  (2)将其从文件目录(*fcb[12])中 删除 (3)释放其在文件结构中的child结点 
	char *savePath = &realFilePath[0];
    if(remove(savePath)==0){
    
		cout<<"删除成功"<<endl;
	}else {
    
		cout<<"删除失败"<<endl;
	}
   //(1)根据其长度释放其firstBlock中的indexList中的物理块(其实不需要长度,根据索引表释放即可)
	int first = tmpF->fcb[i]->firstBlock->phNum;
							
	if(phBlock[first].indexList[0]){
     //如果索引表存在,按照索引表删 
		for(int k=0;k<300;k++){
    
			if( phBlock[first].indexList[k] ){
    
				phBlock[phBlock[first].indexList[k]].state = 0;
				phBlock[phBlock[first].indexList[k]].content = "";
			}
		}
		phBlock[first].state = 0;
		phBlock[first].content = "";
						    
	
		//(2)将其从文件目录(*fcb[12])中 删除
		free(tmpF->fcb[i] );
		tmpF->fcb[i] = NULL;
							 
		//(3)释放其在文件结构中的child结点 
		free(tmpF->child[i]);
		tmpF->child[i] = NULL;
	}
						
	else{
    //如果不存在索引表,那么这个文件整个内容都存在firstBlock物理块 
	//	cout<<"索引表不存在!" <<endl;
		phBlock[first].state = 0;
		phBlock[first].content = "";
							
		//(2)将其从文件目录(*fcb[12])中 删除
		free(tmpF->fcb[i] );
		tmpF->fcb[i] = NULL;
							 
		//(3)释放其在文件结构中的child结点 
		free(tmpF->child[i]);
		tmpF->child[i] = NULL;
	} 
} 

//递归删除一个文件夹 
void rm_rf(string realFilePath,FSct *tmpF,int j) {
    
	FSct *Origin = tmpF;
    	for(int i=0;i<12;i++){
    
    		if(!tmpF->child[j]->fcb[i]) {
    
    			continue;
			}else{
    
			}
			
			if(tmpF->child[j]->child[i] && tmpF->child[j]->fcb[i]->type == "—" ) 
			 {
    
			 	string newFilePath = tmpF->child[j]->child[i]->filePath;
         		rm_f(newFilePath,tmpF->child[j],i);
			 }
			
			
			else if(tmpF->child[j]->child[i] && tmpF->child[j]->fcb[i]->type == "dir" ) 
			{
    
				string newFilePath = tmpF->child[j]->child[i]->filePath;
				//对目录进行递归,直到找到文件 
				rm_rf(newFilePath,tmpF->child[j],i);
				
				//待文件删完了之后还要释放目录的结点 
				int first = tmpF->child[j]->fcb[i]->firstBlock->phNum;
				phBlock[first].state = 0;
				phBlock[first].content = "";
							
				//(2)将其从文件目录(*fcb[12])中 删除
				free(tmpF->child[j]->fcb[i] );
				tmpF->child[j]->fcb[i] = NULL;
				
				//(3)释放其在文件结构中的child结点 
				free(tmpF->child[j]->child[i]);
				tmpF->child[j]->child[i] = NULL;
				
	            bool flag = RemoveDirectory(newFilePath.c_str());	
         	}
    	}
		string dirPath = Origin->child[j]->filePath;
		int first = Origin->fcb[j]->firstBlock->phNum;
		phBlock[first].state = 0;
		phBlock[first].content = "";
							
		//(2)将其从文件目录(*fcb[12])中 删除
		free(Origin->fcb[j] );
		Origin->fcb[j] = NULL;
	//	cout<<"文件控制块的j值:"<<j<<endl; 
				
		//(3)释放其在文件结构中的child结点 
		free(Origin->child[j]);
		Origin->child[j] = NULL;
				
	    bool flag = RemoveDirectory(dirPath.c_str());
	
    }
    
    
    //find命令 (递归查找)
int find(string path,string fileName,string username)
{
    
	vector<string> fileNames;
	//文件句柄
	intptr_t hFile = 0;
	
	
	//文件信息
	struct _finddata_t fileinfo;
	string p;
	int flag = 0; 
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
    
		do
		{
    
			if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
			
			if ((fileinfo.attrib & _A_SUBDIR))//判断是否是文件夹 
			{
    
				if(fileName == fileinfo.name){
    
					
					string realPath = path+"\\"+fileinfo.name+"\\";
					cout<<fileinfo.name<<"\\:\t"<<realPath<<endl;
					flag=1;
				}
				else{
    
					string newPath = path+"\\"+fileinfo.name;
					int num = find(newPath,fileName,username);
					flag = num;//这个递归的出口不传值的话只要是二层以下的文件夹回调,都会使得flag被从新赋值成开头定义的flag=0; 
				}
			}
			
			else{
    
				
				if(fileName == fileinfo.name){
    
					string realPath = path+"\\"+fileinfo.name;
					cout<<fileinfo.name<<":"<<realPath<<endl;
					flag=1;
				}
			}
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	}
	
	return flag;
	
}

//返回一个文本的行数 
int getlineNum(string path){
    
    ifstream in(path);
    string line;
    int i=0;
 
    if(in) // 有该文件
       while (getline (in, line))  i++;
       
        
    else // 没有该文件
       cout <<"no such file" << endl;
     
    in.close();
    return i; 
}


//读文件命令 
int cat(string path){
    
	SetConsoleOutputCP(65001);
    ifstream in(path);
    string line;
    int i=0;
 
    if(in) // 有该文件
       while (getline (in, line)){
    
       	i++;
       	cout<< line <<endl;
	   }  

    else // 没有该文件
       cout <<"no such file" << endl;
    in.close();
    SetConsoleOutputCP(936);

    return i; 
}

//读取文件头num行 
int head(string path,int num){
    
	SetConsoleOutputCP(65001);
    ifstream in(path);
    string line;
    int i=0;
 
    if(in) // 有该文件
       while (getline (in, line)){
    
       	i++;
       	cout<< line <<endl;
       	if(i>num){
    
       		break;
		   }
	   }  

    else // 没有该文件
       cout <<"no such file" << endl;
       
    in.close();
    //system("pause");
     SetConsoleOutputCP(936);

    return i; 
}


//读取文件尾几行
int tail(string path,int num){
    
	SetConsoleOutputCP(65001);
    ifstream in(path);
    string line;
    int i=0;
 
    if(in) // 有该文件
       while (getline (in, line)){
    
       	i++;
       	
       	if(i>=num){
    
       		cout<< line <<endl;
		   }
	   }  
       
        
    else // 没有该文件
       cout <<"no such file" << endl;
       
    in.close();
    //system("pause");
     SetConsoleOutputCP(936);

    return i; 
}


//按照文件绝对路径递归查找 
FSct * search(FSct *find,string dst_real_dir){
    
	FSct *result;
	for(int i=0;i<12;i++){
    
		
		//如果结点不存在或结点类型是文件则直接跳过 
		if(!find->fcb[i] || find->fcb[i]->type == "—") continue;
		
		else if(find->child[i]->filePath == dst_real_dir && find->fcb[i]->type == "dir")
		{
    
			result = find->child[i];	
			break;//操作结束直接break 
		}
		
		else if(find->child[i]->filePath != dst_real_dir && find->fcb[i]->type == "dir")
		{
    
			result = search(find->child[i],dst_real_dir);
		}
	}
	
	return result;
}


//在cp和move指令中处理输入路径(虚拟路径->真实路径) 
string deal_path(string dst_path,string f){
    
	//cout<<"源字符串:"<<dst_path<<endl;
	//cout<<"真实路径前缀:"<<f<<endl; 

	int last = dst_path.find_last_of("\\");
	//cout<<"last :"<<last<<endl;
	
	int first = dst_path.find_first_of("\\");
	//cout<<"first: "<<first<<endl;
	
	string dst_dir = dst_path.substr(first,last-first);//这个是目标文件夹路径 
	//cout<<"标文件夹路径 :"<<dst_dir<<endl;
	
	string dst_fileName = dst_path.substr(last+1,dst_path.length());
	//cout<<"新生成的文件名:"<< dst_fileName<<endl;
	
	string dst = f+dst_dir;
	//cout<<"真实的路径:"<<dst<<endl;
	
	return dst;
}

//copy函数 
void copy(string source,string destination){
    
	char *src = &source[0];
	char *dst = &destination[0];
	CopyFile(src,dst,FALSE);//false代表覆盖,true不覆盖	
}


//覆盖 写文件 
void cover(string path){
    
	
	ofstream  ofs; //2.创建流对象 
	cout<<"请输入写入内容并以#end结束:"<<endl;
	ofs.open(path,ios::out);//3.打开文件(out模式为覆盖) 
   
    string content;
    while(1){
    
    	cin>>content; 
    	if(content != "#end")
    	   ofs<<content<<" ";
    	else break;
	}
	 ofs.close();//4.关闭文件	
} 


//追加 写文件 
void app(string path){
    
	
	ofstream  ofs; //2.创建流对象 
	cout<<"请输入写入内容并以#end结束:"<<endl;
    ofs.open(path,ios::app);//3.打开文件(app模式为追加)
    string content;
    ofs<<endl;
    
    while(1){
    
    	cin>>content; 
    	if(content != "#end")
    	   ofs<<content<<" ";
    	else break;
	}
	 ofs.close();//4.关闭文件	
} 




//控制台函数 
void cd(User u,FSct *f){
    
	string username = u.username;
	string tmpPath = f->fileName;
	FSct *tmpF;// = new FSct;
	FSct *preF;
	tmpF = f;
	preF = f;
	string prePath = tmpPath;
	
	if(f->fcb[0]){
    
		string f_path = f->child[0]->filePath.substr(0,f->child[0]->filePath.find_last_of("\\"));
		f->filePath = f_path;
	}
	while(1){
    
		cout<<"localhost@"<<tmpPath<<":";
		string tmpOrder;
		cin>> tmpOrder;
		

//__________________________________________________cd
		if(tmpOrder == "cd"){
    
			string newPath;
			cin>>newPath;
			
			if(newPath == "home"){
    
				tmpPath = f->fileName;
				tmpF = f;
				preF = f;
			}
			
			else if(newPath == "../"){
    
				if(prePath.empty()){
    
					cout<<"No such file !"<<endl;
				}else{
    
					tmpPath = prePath;
					
					//prePath需要更新
					int num = prePath.find_last_of("\\");
                    prePath = prePath.substr(0,num); 
				    string old_path = tmpF->filePath;
				    string tf = old_path.substr(0,old_path.find_last_of("\\"));
				    
				    if(preF==f){
    
				    	tmpF = f;
					}else{
    
						tmpF = search(f,tf);
					}
				    string pf = tf.substr(0,tf.find_last_of("\\"));

				    
				    int judge = 0;
				    for(int i=0;i<12;i++){
    
				    	if(!f->fcb[i]) continue;
				    	else if(tmpF->fileName == f->child[i]->fileName){
    
				    		preF = f;
				    		judge = 1;
						}
					}
				    
				    if(judge == 0)
				       preF = search(f,pf);
					if(preF == NULL || tmpF == f){
    
						preF = f;
					}
				} 
			}
			
			else if(newPath == "./"){
    	}
			
			else{
    
			//if(newPath的确存在)
			int flag = 0;
			for(int i=0;i<12;i++){
    
				if(tmpF->fcb[i] && tmpF->fcb[i]->fileName == newPath &&tmpF->fcb[i]->type == "dir"){
    
					flag = 1;
					prePath = tmpPath;
		         	tmpPath += "\\"+newPath; 
		         	
		         	if(tmpF->child[i]->child[1]){
    
		         		FSct *sec = tmpF->child[i]->child[1];

		         	    preF = tmpF;
		         	    FSct *t = tmpF->child[i]; 
		         	    tmpF = t;
		         	    tmpF->pre = preF;
		         	
		         	    tmpF->child[1] = sec;
					 }else{
    
					 	preF = tmpF;
		         	    FSct *t = tmpF->child[i]; 
		         	    tmpF = t;
		         	    tmpF->pre = preF;
					 }
		         	break;
				}
				
				if(tmpF->fcb[i] && tmpF->fcb[i]->fileName == newPath &&tmpF->fcb[i]->type == "—"){
    
					cout<<"Not a directory!"<<endl; 
					flag = 1;
				}
			}
			if(flag == 0){
    
				cout<<"No such file !"<<endl;
			}
			}
		}
//__________________________________________________cd


    else if(tmpOrder == "help"){
    
    	help();
	}

//__________________________________________________ls
	    else if(tmpOrder == "ls"){
    
	    	
				ls_alh_ByTree(tmpF);
			
		}	
//__________________________________________________ls

//__________________________________________________touch(注意这里创建的是一个空文件,不用考虑给其所属的文件夹增长,但在后续操作中需要给其父目录增长)

        else if(tmpOrder == "touch"){
    
        	string tmpFileName;
        	cin>>tmpFileName;
        	string realFilePath = tmpF->filePath+"\\"+tmpFileName;
        	create_txt(realFilePath); 
        	
        	//创建完了还不算完,还要在虚拟磁盘上有所体现
        	for(int i=0;i<12;i++){
    
        		if(tmpF->fcb[i] == NULL){
    
        			//文件控制块FCB的处理 
        			tmpF->fcb[i] = new FCB;
        			tmpF->fcb[i]->innerNum = i;
        			tmpF->fcb[i]->fileName = tmpFileName;
        			tmpF->fcb[i]->authority = 666;
        			tmpF->fcb[i]->type = "—";
        			tmpF->fcb[i]->length = 0;//创建文件的时候是空文件,长度为零 
        			tmpF->fcb[i]->Owner[0] = new User;
        			tmpF->fcb[i]->Owner[0]->username = u.username;
        			
        			//文件结构的处理
					tmpF->child[i] = new FSct;
					tmpF->child[i]->fileName = tmpFileName;
					tmpF->child[i]->filePath = realFilePath;
				
					//物理块的处理 
					for(long int num=0; num<1024*1024; num++){
    
						if(phBlock[num].state == 0){
    
							tmpF->fcb[i]->phNum = num;
							phBlock[num].state = 1;
							phBlock[num].content = ("complete of "+ tmpFileName);
							
							
							//开辟物理块 
			                tmpF->fcb[i]->firstBlock = new PHB;//将该FCB指向其首物理块
			                tmpF->fcb[i]->firstBlock->state = 1; //表示此块已被占用 
			                tmpF->fcb[i]->firstBlock->phNum = num;//物理块内部标识的物理块号
			                 
			                cout<<"文件"<<tmpF->child[i]->fileName<<"创建成功,(首)物理块号为:"<<tmpF->fcb[i]->phNum<<"  "<<endl;
			                break; //注意这个break要写在if语句的里面 
						}
					} 
        			break;
				}
			} 	
		}


//__________________________________________________touch(创建文件)


//__________________________________________________write命令 (写文件)
    else if(tmpOrder == "write"){
    
    	string Option;
    	cin>> Option;
		string file_name;
		cin>>file_name;
   	int flag;
   	for(int i=0;i<12;i++){
    
   		if(!tmpF->fcb[i]) continue;
   		
   		else if(file_name == tmpF->fcb[i]->fileName){
      //在文件结构中找到该文件 
   			flag=1;
   			ASL *p = Shead->next;
   			while(p){
    
   				
   				if(p->fileName == file_name){
      // 在文件活动名表 和 活动符号表中找到该文件 
                	
   					string file_path = p->path;
   					
   					//分类 ,是追加还是覆盖
					   
					if(Option == "-a"){
    
						app(file_path);
						flag = 2;
					} 

					else if(Option == "-c"){
    
						cover(file_path);
						flag = 2;
					}
					
					//更新长度
					tmpF->fcb[i]->length = get_length(file_path);
					for(int j=0;j<12;j++){
    
						if(!tmpF->pre->fcb[j]) continue;
						else if(tmpF->pre->child[j]->filePath == tmpF->filePath){
    
							tmpF->pre->fcb[j]->length  += get_length(file_path);
						}
					}

					//根据新长度更新物理块 
   					if(tmpF->fcb[i]->length < 1)
			        {
    
			            //处理在初始化就分配好的块 
				       tmpF->fcb[i]->firstBlock->content = ("complete file of "+tmpF->fcb[i]->fileName);
					   long int phNum = tmpF->fcb[i]->firstBlock->phNum;
					   string tmpContent = ("complete file of "+tmpF->fcb[i]->fileName);
					   phBlock[phNum].content =tmpContent;
			        }
			
			        else if(tmpF->fcb[i]->length > 1)
			        {
    
				       //先处理在初始化就分配好的块 
					   tmpF->fcb[i]->firstBlock->content = ("IndexBlock of "+tmpF->fcb[i]->fileName);
					   long int phNum = tmpF->fcb[i]->firstBlock->phNum;
					   phBlock[phNum].content = ("IndexBlock of "+tmpF->fcb[i]->fileName);
				       int count = tmpF->fcb[i]->length/1.0;
					   if(tmpF->fcb[i]->length > count+0.5) count++;//count为实际要为该文件分配的块数 
				
				        //再处理根据索引表还要分配的块 
				       int tmpNum = 0;
					   for(long int num=0;num < 1024*1024; num++){
    
					      if(phBlock[num].state==0 && tmpNum<=count){
    
						    phBlock[num].state = 1;
							string tmpContent = ("Parts file of "+tmpF->fcb[i]->fileName);
							phBlock[num].content = tmpContent;
						
						    int first = tmpF->fcb[i]->firstBlock->phNum;
						    phBlock[first].indexList[tmpNum] = num; //还要处理动态分配数组 
						    tmpNum++;
					      }
				          if(tmpNum == count) break;
				       }
			        }
   					break;
				   }
				else{
    
					p=p->next;
				}
			}	
		}
	}
   	if(flag == 0){
    
   		cout<<"No such file!"<<endl;
	}else if(flag == 1){
    
		cout<<"file hasNot been opend !"<<endl;
	}
  } 
//__________________________________________________now(查看当前文件结构) 

else if(tmpOrder == "now"){
    
	cout<<"当前文件结构:"<<tmpF->fileName<<endl;
	cout<<"当前文件父结构:"<<preF->fileName<<endl; 
}
   

//__________________________________________________now(查看当前文件结构) 


//__________________________________________________df(查看磁盘使用情况) 
        else if(tmpOrder == "df") {
    
        	check_Block_Content();
            check_phBlock();
		}
//__________________________________________________df(查看磁盘使用情况)

//__________________________________________________rm -f/-rf(删除文件/目录)

        else if(tmpOrder == "rm"){
      //删除文件或者文件夹的时候记得要处理其物理块 
        	string Option;
        	cin>>Option;
        	
        	if(Option == "-f")                            //rm -f:删除文件 
        	{
    
        		string tmpFileName;
        	    cin>>tmpFileName;
        		string realFilePath = tmpF->filePath+"\\"+tmpFileName;
        		for(int i=0;i<12;i++){
    
        			if(tmpF->child[i] && tmpF->child[i]->fileName == tmpFileName){
    
        		if(tmpF->fcb[i]->type == "—"){
    
        		    rm_f(realFilePath,tmpF,i);//删除一个文件的操作 
				}
				else if(tmpF->fcb[i]->type == "dir"){
    
							cout<<"Not a File!It is a directory !"<<endl;
							break;
						}
						break; 
					}
				}
			}
			
			else if(Option == "-rf")                                   //rm -rf(删除文件夹) 
			{
    
				cout<<"in rm -rf process"<<endl; 
				string tmpFileName;
        	    cin>>tmpFileName;
        		string realFilePath = tmpF->filePath+"\\"+tmpFileName;
        		for(int i=0;i<12;i++){
    
        		
        			if(tmpF->fcb[i] && tmpF->child[i]->fileName == tmpFileName && tmpF->fcb[i]->type == "dir"){
    
        		       rm_rf(realFilePath,tmpF,i);
        		       break;
        		    }
        	    }
			}	
		}
		
//__________________________________________________rm -f/-rf(删除文件/目录)

//__________________________________________________mkdir (创建文件夹) 

		else if(tmpOrder == "mkdir"){
    
			string tmpFileName;
        	cin>>tmpFileName;
        	
        	string realFilePath = tmpF->filePath+"\\"+tmpFileName;
         	bool flag = CreateDirectory(realFilePath.c_str(), NULL);
	        if(flag == true){
    
	        	cout<<"创建文件夹成功!"<<endl; 
			}else{
    
				cout<<"创建文件夹失败!"<<endl;
			} 
        	//创建完了还不算完,还要在虚拟磁盘上有所体现
        	for(int i=0;i<12;i++){
    
        		if(tmpF->fcb[i] == NULL){
    
        			tmpF->fcb[i] = new FCB;
        			tmpF->fcb[i]->innerNum = i;
        			tmpF->fcb[i]->fileName = tmpFileName;
        			tmpF->fcb[i]->authority = 666;
        			tmpF->fcb[i]->type = "dir";
        			tmpF->fcb[i]->length = 0;
        			tmpF->fcb[i]->Owner[0] = new User;
        			tmpF->fcb[i]->Owner[0]->username = u.username;
        			
        			//文件结构的处理
					tmpF->child[i] = new FSct;
					tmpF->child[i]->fileName = tmpFileName; 
					tmpF->child[i]->filePath = realFilePath;
				
					
					
					//物理块的处理 
					for(long int num=0; num<1024*1024; num++){
    
						if(phBlock[num].state == 0){
    
							tmpF->fcb[i]->phNum = num;
							phBlock[num].state = 1;
							phBlock[num].content = ("DirBlock of "+ tmpFileName);
							
							
							//开辟物理块 
			                tmpF->fcb[i]->firstBlock = new PHB;//将该FCB指向其首物理块
			                tmpF->fcb[i]->firstBlock->state = 1; //表示此块已被占用 
			                tmpF->fcb[i]->firstBlock->phNum = num;//物理块内部标识的物理块号
			                 
			                cout<<"文件夹"<<tmpF->child[i]->fileName<<"创建成功,(首)物理块号为:"<<tmpF->fcb[i]->phNum<<"  "<<endl;
			                break; //注意这个break要写在if语句的里面 
						}
					} 
        			break;
				}
			} 
        	
		} 
//__________________________________________________mkdir (创建文件夹) 

//__________________________________________________find命令 
    else if(tmpOrder == "find"){
    
    	string fileName;
    	cin>>fileName;
    	int flag = find(tmpF->filePath,fileName,u.username);
    	//cout<<"flag:"<<flag<<endl; 
    	if(flag == 0){
    
    		cout<<"-bash- : NO such file!"<<endl;
		}
	} 
//__________________________________________________find命令 


//__________________________________________________open命令 
    else if(tmpOrder == "open") {
    
    	int flag = 0;
    	string file_name;
    	cin>>file_name;
    	for(int i=0;i<12;i++){
    
    		if(tmpF->fcb[i] == NULL) continue;
    		
    		else{
    
    			//找到目标文件,做打开操作 
    			if(tmpF->child[i]->fileName == file_name && tmpF->fcb[i]->type == "—"){
    
    				//cout<<"Found!"<<endl;
    				
    				//对活动文件表分配
					AFL *t = Fhead;
					//cout<<"Found!"<<endl;
					while(t->next != NULL){
    
    					t = t->next;
					}//循环结束后p指向最后一个结点
					//cout<<"Found!"<<endl;
    				t->next = new AFL;
    				//cout<<"Found!"<<endl;
    				t = t->next;
    				t->fcb = tmpF->fcb[i];
    				//cout<<"Found!"<<endl;
    			    t->next = NULL;
    				
    				
    				
    				
    				//对符号名表分配 
    				ASL *p = Shead;
    				while(p->next != NULL){
    
    					p = p->next;
					}//循环结束后p指向最后一个结点
					p->next = new ASL;
					p=p->next;
					p->fileName =  tmpF->child[i]->fileName;
					p->path = tmpF->child[i]->filePath; 
					p->innerNum = tmpF->fcb[i]->innerNum;
					p->next = NULL;
					p->afl = t;
					
					
    				FileNum_Curr++; 
    				flag = 1;
    				cout<<p->fileName<<"文件已打开,当前活动文件数:"<< FileNum_Curr<<endl;
    				
    				
				}else if(tmpF->child[i]->fileName == file_name && tmpF->fcb[i]->type == "dir"){
    
					cout<<"Not a file! It's a directory!"<<endl;
					flag = 1;	
				}
    			
			}
		}
		if(flag == 0){
    
			cout<<"No such file!"<<endl;
		}
	}

//__________________________________________________open命令 

//__________________________________________________close命令 
    else if(tmpOrder == "close"){
    
    	string file_name;
    	cin>>file_name;
    		
    		
		ASL *p = Shead;
		int flag = 0;
		while(p->next){
    
			
			if(p->next->fileName == file_name)
			{
    
				cout<<"Remove from ASL!"<<endl;
				ASL *tmp = p->next;
				p->next = tmp->next;
				delete(tmp);
				flag = 1;
				break;
			}
			
			else
			{
    
				p = p->next;
			}
		}
		
		
		if(flag == 1){
    
			AFL *t = Fhead;
			while(t->next){
    
				if(t->next->fcb->fileName == file_name)
				{
    
					cout<<"Remove from AFL!"<<endl;
					AFL *tmp = t->next;
					t->next = tmp->next;
					delete(tmp);
					FileNum_Curr--;
					cout<<"关闭文件成功!"<<'\t'<<"当前活动文件数:"<<FileNum_Curr<<endl; 
				}
				
				else
				{
    
					t = t->next;
				}
			}	
		}else{
    
			cout<<"关闭文件失败!"<<endl;
		}	
	}

//__________________________________________________close命令 

//__________________________________________________ASL命令 (查看活动符号名表)
    else if(tmpOrder == "ASL"){
    
    	
    	cout<<"当前活动文件数:"<<FileNum_Curr<<endl;
    	
    	ASL *p = Shead->next;
    	if(!p){
    
    		cout<<"当前没有活动文件"<<endl; 
		}
		else{
    
			int i=1;
			while(p){
    
				
				cout<<"("<<i<<")  文件名:"<<p->fileName<<'\t'<<"文件内部号:"<<p->innerNum<<'\t'<<"路径:"<<p->path<<endl;
				p=p->next;
				i++; 
			}
		}
    	
    	
	} 

//__________________________________________________ASL命令 (查看活动符号名表)

//__________________________________________________cat命令 (读文件)
   else if(tmpOrder == "cat"){
    
   	
   	string file_name;
   	cin>>file_name;
   	int flag;
   	for(int i=0;i<12;i++){
    
   		if(!tmpF->fcb[i]) continue;
   		
   		else if(file_name == tmpF->fcb[i]->fileName){
    
   			flag=1;
   			ASL *p = Shead->next;
   			while(p){
    
   				
   				if(p->fileName == file_name){
    
                	
   					string file_path = p->path;
   					int tmpnum = cat(file_path);
   					//int tmpnum2 = getlineNum(path);
   					flag = 2;
   					
   					break;
				   }
				else{
    
					p=p->next;
				}
			}	
		}
	}
   	if(flag == 0){
    
   		cout<<"No such file!"<<endl;
	}else if(flag == 1){
    
		cout<<"file hasNot been opend !"<<endl;
	}

  } 


//__________________________________________________cat命令 (读文件)

//__________________________________________________head命令 (读文件头几行)

    else if(tmpOrder == "head"){
    
    	string Option;
    	cin>>Option;
    	string file_name;
    	cin>>file_name;
    	
    	string subOption = Option.substr(1,Option.length());
        int num = stoi(subOption.c_str());//将string强制转为int 
        
        int flag = 0;
        for(int i=0;i<12;i++){
    
   		if(!tmpF->fcb[i]) continue;
   		
   		else if(file_name == tmpF->fcb[i]->fileName){
    
   			flag=1;
   			ASL *p = Shead->next;
   			while(p){
    
   				
   				if(p->fileName == file_name){
    
                	
   					string file_path = p->path;
   					int tmpnum = head(file_path,num);

   					flag = 2;
   					
   					break;
				   }
				else{
    
					p=p->next;
				}
			}	
		}
	}
   	if(flag == 0){
    
   		cout<<"Read file fail!"<<endl;
	}else if(flag == 1){
    
		cout<<"file hasNot been opend !"<<endl;
	}
   	
   	
   } 
//__________________________________________________head命令 (读文件头几行)

//__________________________________________________tail命令 (读文件尾部几行)

    else if(tmpOrder == "tail"){
    
    	string Option;
    	cin>>Option;
    	string file_name;
    	cin>>file_name;
    	
    	string subOption = Option.substr(1,Option.length());
        int tmp_num = stoi(subOption.c_str());//将string强制转为int 
        
        
        int flag = 0;
        for(int i=0;i<12;i++){
    
   		if(!tmpF->fcb[i]) continue;
   		
   		else if(file_name == tmpF->fcb[i]->fileName){
    
   			flag=1;
   			ASL *p = Shead->next;
   			while(p){
    
   				
   				if(p->fileName == file_name){
    
                	
   					string file_path = p->path;
   					
   					int file_line_length = getlineNum(file_path);
   					int num = file_line_length - tmp_num;
   					int tmpnum = tail(file_path,num);

   					flag = 2;
   					
   					break;
				   }
				else{
    
					p=p->next;
				}
			}	
		}
	}
   	if(flag == 0){
    
   		cout<<"Read file fail!"<<endl;
	}else if(flag == 1){
    
		cout<<"file hasNot been opend !"<<endl;
	}
   } 
//__________________________________________________tail命令 (读文件尾部几行)



//__________________________________________________cp命令 (复制文件)

/*
cp命令格式:   cp   当前目录下的文件    目标文件路径\\复制后的文件名 

需要注意的点:
(1) 解析目标路径,找到目录结构树中的对应结点
(2)取dst和src的path,调用window.h实现实际结构的copy
(3)在目录结构树的目标路径下new出新的 FSct* 结点,根据源文件的信息填写新结点的信息
(4)需要根据其长度重新setBlock,注意是单独的setBlock 
*/ 

   else if(tmpOrder == "cp") {
    
   	
   	string source;
	string destination;
   	
   	string src_name;
   	cin>>src_name;
   	
   	string dst_path;
   	cin>>dst_path;
   	
   	for(int i=0;i<12;i++){
    
   		
   		if(!tmpF->fcb[i])  continue;
		   
		else if(tmpF->child[i]->fileName == src_name and tmpF->fcb[i]->type == "—")
		{
    
			
			cout<<"source file found !"<<endl;
			source = tmpF->child[i]->filePath;
			
			//下面开始解析目标路径 
			string real_path = deal_path(dst_path,f->filePath);
			destination = real_path+"\\"+src_name;
			FSct *dst = search(f,real_path);
			if(real_path == f->filePath) dst = f;
			
			//至此: 
			//source的路径:  tmpF->child[i]->filePath
			//destination的路径: real_path 
			
			
			
			//找到了目标路径的文件夹 dst,做数据分配 (其实在这里可以生成源文件的快捷方式!!直接改指针就行) 
			for(int j =0;j<12;j++){
    
				if(!dst->fcb[j])//找到一个空的fcb块 
				{
    
				
					dst->child[j] = new FSct;
					dst->child[j]->fileName = src_name;//其实目标文件的名称可以自定义,将字符串处理函数写进来就行 
					dst->child[j]->filePath = real_path+"\\"+src_name; 
					
				
					dst->child[j]->Owner[0] = new User;
					dst->child[j]->Owner[0] = f->Owner[0];
					
			
					dst->fcb[j] = new FCB;
					dst->fcb[j]->authority = 666;
				
					dst->fcb[j]->fileName = src_name;
				
					dst->fcb[j]->innerNum = j;
				
					dst->fcb[j]->Owner[0] = new User;
					dst->fcb[j]->Owner[0]->username = u.username;
					dst->fcb[j]->type = "—";
					dst->fcb[j]->length = tmpF->fcb[i]->length;
					
//__________________________________ 
					//物理块的分配
					
				
					for(long int num=0; num<1024*1024; num++){
    
						if(phBlock[num].state == 0){
    
							dst->fcb[j]->phNum = num;
							phBlock[num].state = 1;
							phBlock[num].content = ("complete file of "+ src_name);
							
							
							//开辟物理块 
			                dst->fcb[j]->firstBlock = new PHB;//将该FCB指向其首物理块
			                dst->fcb[j]->firstBlock->state = 1; //表示此块已被占用 
			                dst->fcb[j]->firstBlock->phNum = num;//物理块内部标识的物理块号
			                 
			                cout<<"文件"<<dst->child[j]->fileName<<"复制成功,(首)物理块号为:"<<dst->fcb[j]->phNum<<"  "<<endl;
			                break; //注意这个break要写在if语句的里面 
						}
					} 
					
					
				
				   	if(dst->fcb[j]->length < 1)
			        {
    
				       dst->fcb[j]->firstBlock->content = ("complete file of "+dst->fcb[j]->fileName);
					   long int phNum = dst->fcb[j]->firstBlock->phNum;//注意一下动态分配数组已限定一个文件的最大大小
					
					   string tmpContent = ("complete file of "+dst->fcb[j]->fileName);
					   phBlock[phNum].content =tmpContent;
			        }
			
			        else if(dst->fcb[j]->length > 1)
			        {
    
				       //先处理在初始化就分配好的块 
					   dst->fcb[j]->firstBlock->content = ("IndexBlock of "+dst->fcb[j]->fileName);
					   long int phNum = dst->fcb[j]->firstBlock->phNum;//注意一下动态分配数组已限定一个文件的最大大小
					   phBlock[phNum].content = ("IndexBlock of "+dst->fcb[j]->fileName);
				
				
				       int count = dst->fcb[j]->length/1.0;
					   if(dst->fcb[j]->length > count+0.5) count++;//count为实际要为该文件分配的块数 
				
				
				       int tmpNum = 0;
					   for(long int num=0;num < 1024*1024; num++){
    
					      if(phBlock[num].state==0 && tmpNum<=count){
    
						    phBlock[num].state = 1;
							string tmpContent = ("Parts file of "+dst->fcb[j]->fileName);
							phBlock[num].content = tmpContent;
						
						    int first = dst->fcb[j]->firstBlock->phNum;
						    phBlock[first].indexList[tmpNum] = num; //还要处理动态分配数组 
						    tmpNum++;
					      }
				          if(tmpNum == count) break;
				       }
			        }
//__________________________________ 
					
					copy(source,destination);
			        cout<<"文件复制成功!"<<endl; 
			        break;
				 } 
			}
		}  		
	  }
   }

//__________________________________________________cp命令 (复制文件)


//__________________________________________________move命令 (移动文件)

/*
move命令格式:   move   当前目录下的文件    目标文件路径\\移动后的文件名 

需要注意的点:
(1) 解析目标路径,找到目录结构树中的对应目标父结点
(2)取dst和src的path,调用window.h实现实际结构的move指令 
(3)使得目标路劲结点父目录的child【j】指向源文件 
(4)使得目标路劲结点父目录的fcb【j】指向源文件的fcb 
(5)物理块无需变动 
*/ 

else if(tmpOrder == "move") {
    
   	
   	string source;
	string destination;
   	
   	string src_name;
   	cin>>src_name;
   	
   	string dst_path;
   	cin>>dst_path;
   	
   	for(int i=0;i<12;i++){
    
   		
   		if(!tmpF->fcb[i])  continue;
		   
		else if(tmpF->child[i]->fileName == src_name and tmpF->fcb[i]->type == "—")
		{
    
			
			cout<<"source file found !"<<endl;
			source = tmpF->child[i]->filePath;
			
			//下面开始解析目标路径 
			string real_path = deal_path(dst_path,f->filePath);
			destination = real_path+"\\"+src_name;
			FSct *dst = search(f,real_path);
			if(real_path == f->filePath) dst = f;
			
			//至此: 
			//source的路径:  tmpF->child[i]->filePath
			//destination的路径: real_path 
			
			
			//找到了目标路径的文件夹 dst,做数据分配 (其实在这里可以生成源文件的快捷方式!!直接改指针就行) 
			for(int j =0;j<12;j++){
    
				if(!dst->fcb[j])//找到一个空的fcb块 
				{
    
				
					dst->child[j] = new FSct;
					dst->child[j]->fileName = src_name;//其实目标文件的名称可以自定义,将字符串处理函数写进来就行 
					dst->child[j]->filePath = real_path+"\\"+src_name; 
					
				
					dst->child[j]->Owner[0] = new User;
					dst->child[j]->Owner[0] = f->Owner[0];
					
			
					dst->fcb[j] = new FCB;
					dst->fcb[j]->authority = 666;
				
					dst->fcb[j]->fileName = src_name;
				
					dst->fcb[j]->innerNum = j;
				
					dst->fcb[j]->Owner[0] = new User;
					dst->fcb[j]->Owner[0]->username = u.username;
					dst->fcb[j]->type = "—";
					dst->fcb[j]->length = tmpF->fcb[i]->length;
					
					//更改物理块的内容和链接
					dst->fcb[j]->firstBlock = new PHB;
					dst->fcb[j]->firstBlock = tmpF->fcb[i]->firstBlock;
					dst->fcb[j]->phNum = dst->fcb[j]->firstBlock->phNum;
					
					copy(source,destination);
			        //cout<<"文件复制成功!"<<endl; 
			        
			        
			        //释放源文件的所有链接和结点
					//(1)将其从文件目录(*fcb[12])中 删除
		            free(tmpF->fcb[i] );
					tmpF->fcb[i] = NULL;
								 
		            //(2)释放其在文件结构中的child结点 
					free(tmpF->child[i]);
					tmpF->child[i] = NULL;
					
					char *savePath = &source[0];
					if(remove(savePath)==0){
    
					   cout<<"文件移动成功"<<endl;
					}else {
    
					   cout<<"文件移动失败"<<endl;
					}
			        break;
				 } 
			}
		}  		
	  }
   }
//__________________________________________________move命令 (移动文件)



//__________________________________________________export命令 (将虚拟磁盘上的文件导出到 c 盘/任意本地文件夹)

   else if(tmpOrder == "export") {
    
   	
   	string src_file; //虚拟磁盘上的导出文件 
   	cin>>src_file;
   	
	string destination; //c 盘/任意本地文件夹
	cin>>destination;
	
	for(int i=0;i<12;i++) {
    
		if(!tmpF->fcb[i]) continue;
		
		else if(tmpF->child[i]->fileName == src_file){
    
			cout<<"Found source file !"<<endl; 
			string source = tmpF->child[i]->filePath;
			copy(source,destination);
			cout<<"Export succeed !"<<endl; 
			break;
		}
	}
}

//__________________________________________________export命令 (将虚拟磁盘上的文件导出到 c 盘/任意本地文件夹)

// __________________________________________________import命令 (将虚c 盘/任意本地文件夹导入到拟磁盘上的文件 )

    else if(tmpOrder == "import"){
    
    	string destination;
    	string source;
		cin>>source;
		
		string dst_fileName;
		cin>>dst_fileName;
		
		//先找到目标文件并计算其大小 
		double src_length = get_length(source); 
		cout<<src_length<<endl;
		
		for(int i=0;i<12;i++){
    
			if(!tmpF->fcb[i]){
    //找到一个空的物理块 
				
					tmpF->child[i] = new FSct;
					tmpF->child[i]->fileName = dst_fileName;//其实目标文件的名称可以自定义,将字符串处理函数写进来就行 
					tmpF->child[i]->filePath = tmpF->filePath+"\\"+dst_fileName; 
					destination = tmpF->child[i]->filePath;
				
					tmpF->child[i]->Owner[0] = new User;
					tmpF->child[i]->Owner[0] = f->Owner[0];
					
			
					tmpF->fcb[i] = new FCB;
					tmpF->fcb[i]->authority = 666;
				
					tmpF->fcb[i]->fileName = dst_fileName;
				
					tmpF->fcb[i]->innerNum = i;
				
					tmpF->fcb[i]->Owner[0] = new User;
					tmpF->fcb[i]->Owner[0]->username = u.username;
					tmpF->fcb[i]->type = "—";
					tmpF->fcb[i]->length = src_length;
				
//__________________________________ 
					//物理块的分配
						
					for(long int num=0; num<1024*1024; num++){
    
						if(phBlock[num].state == 0){
    
							tmpF->fcb[i]->phNum = num;
							phBlock[num].state = 1;
							phBlock[num].content = ("complete file of "+ dst_fileName);
							
							
							//开辟物理块 
			                tmpF->fcb[i]->firstBlock = new PHB;//将该FCB指向其首物理块
			                tmpF->fcb[i]->firstBlock->state = 1; //表示此块已被占用 
			                tmpF->fcb[i]->firstBlock->phNum = num;//物理块内部标识的物理块号
			                 
			                cout<<"文件"<<tmpF->child[i]->fileName<<"导入成功,(首)物理块号为:"<<tmpF->fcb[i]->phNum<<"  "<<endl;
			                break; //注意这个break要写在if语句的里面 
						}
					} 
					
					
				
				   	if(tmpF->fcb[i]->length < 1)
			        {
    
				       tmpF->fcb[i]->firstBlock->content = ("complete file of "+tmpF->fcb[i]->fileName);
					   long int phNum = tmpF->fcb[i]->firstBlock->phNum;//注意一下动态分配数组已限定一个文件的最大大小
					
					   string tmpContent = ("complete file of "+tmpF->fcb[i]->fileName);
					   phBlock[phNum].content =tmpContent;
			        }
			
			        else if(tmpF->fcb[i]->length > 1)
			        {
    
				       //先处理在初始化就分配好的块 
					   tmpF->fcb[i]->firstBlock->content = ("IndexBlock of "+tmpF->fcb[i]->fileName);
					   long int phNum = tmpF->fcb[i]->firstBlock->phNum;//注意一下动态分配数组已限定一个文件的最大大小
					   phBlock[phNum].content = ("IndexBlock of "+tmpF->fcb[i]->fileName);
				
				
				       int count = tmpF->fcb[i]->length/1.0;
					   if(tmpF->fcb[i]->length > count+0.5) count++;//count为实际要为该文件分配的块数 
				
				
				       int tmpNum = 0;
					   for(long int num=0;num < 1024*1024; num++){
    
					      if(phBlock[num].state==0 && tmpNum<=count){
    
						    phBlock[num].state = 1;
							string tmpContent = ("Parts file of "+tmpF->fcb[i]->fileName);
							phBlock[num].content = tmpContent;
						
						    int first = tmpF->fcb[i]->firstBlock->phNum;
						    phBlock[first].indexList[tmpNum] = num; //还要处理动态分配数组 
						    tmpNum++;
					      }
				          if(tmpNum == count) break;
				       }
			        }
//__________________________________ 
				    copy(source,destination);
			        cout<<"Import succeed!"<<endl; 
			        break;
			}
		} 
	} 
// __________________________________________________import命令 (将虚c 盘/任意本地文件夹导入到拟磁盘上的文件 )
		else{
    
			cout<<"input error!"<<endl;
		}
	}
}

// 线程的运行函数
void* operation(void* args)
{
    
   	Initial(path);
	Initial_Sec_All();
	cout<<"——————————————————————————————————————————"<<endl;
	int key = -1;
	help(); 
	while(key == -1){
    
		key = index();
		if(key != -1) break;
	}
    cd(uGroup[key],home->child[key]);
    
	return 0;
}
 
int main()
{
    
    // 定义线程的 id 变量,多个变量使用数组
    pthread_t tids[NUM_THREADS];
    for(int i = 0; i < NUM_THREADS; ++i)
    {
    
        //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数
        int ret = pthread_create(&tids[i], NULL, operation, NULL);
        if (ret != 0)
        {
    
           cout << "pthread_create error: error_code=" << ret << endl;
        }
    }
    //等各个线程退出后,进程才结束,否则进程强制结束了,线程可能还没反应过来;
    pthread_exit(NULL);
}

3.结语

这个是在大二刚学习完操作系统的时候根据所学到的知识去写的,有些指令Linux并不是这样的但是功能是类似的,另外算法能力还不足,还没充分去考虑性能的问题想到什么功能就花了一周去写了,但结果似乎看起来不差,当时课设95分,发出来看看以后有没有机会再拿出来改一下,也供有类似课设的同学参考,主要还是想涨点浏览量害哈哈哈…

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_47826078/article/details/120164120

智能推荐

android 代码 截取屏幕,如何以编程方式在Android上截取屏幕截图?-程序员宅基地

文章浏览阅读346次。这是允许我的屏幕截图存储在SD卡上的代码,以后用于满足您的任何需求:首先,您需要添加适当的权限来保存文件:这是代码(在Activity中运行):privatevoidtakeScreenshot(){Datenow=newDate();android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss",now);try{//i..._屏幕部分截图android代码

注册表禁用计算机管理,Win7注册表编辑器被管理员禁用的解除方法-程序员宅基地

文章浏览阅读2.7k次。熟悉Win7系统的朋友都知道,注册表编辑器是更改Win7系统设置的好工具。在注册表中可以完成控制面板中不能修改的设置。但是有些用户打开注册表编辑器的时候却被提示,注册表编辑器已被管理员禁用,这是怎么回事呢?如何解除Win7对注册表编辑器的限制呢?一、Win7打开注册表的方法1 Win+R键打开Win7系统的运行,在运行数输入regedit点击确定。二、注册表被禁用解除方法Win7注册表编辑器被管理..._注册表编辑器禁用和解除原因

mysql innodb 源码_【InnoDB源码分析】Redo log-程序员宅基地

文章浏览阅读502次。【版本:mysql-8.0.12】1. Mini Transaction(mtr)InnoDB会将事务执行过程拆分为若干个Mini Transaction(mtr),每个mtr包含一系列如加锁,写数据,写redo,放锁等操作。举个例子:void btr_truncate(const dict_index_t *index) {... ...page_size_t page_size(space-&..._mysql innodb 源代码 解读

matlab背景设置_preferences: path: c:\users\administrator\appdata\-程序员宅基地

文章浏览阅读515次。打开C:\Users\Administrator\AppData\Roaming\MathWorks\MATLAB\R2015b\matlab.prf修改为#MATLAB Preferences#Sat Jul 11 15:54:49 CST 2020Editor.VariableHighlighting.Color=C-6931898EditorMRUSize=I8ReplaceSearchText19=SReplaceSearchText18=SReplaceSearchText17=S_preferences: path: c:\users\administrator\appdata\roaming\mathworks\matlab\c

谁说技术男不浪漫!90后程序员2天做出情绪...-程序员宅基地

文章浏览阅读75次。点击上方[全栈开发者社区]→右上角[...]→[设为星标]点击领取全栈资料:全栈资料9月1日,一则关于#程序员2天做出猫咪情绪识别软件#的话题登上微博热搜,参与阅读的人数达到了82..._程序员自研

解决SpringBoot整合redis下的键值序列化的问题_spring boot redis 查询序列化key-程序员宅基地

文章浏览阅读1.3k次。文章目录思考redis实现键值序列化自定义一个序列化转换器编写redis配置文件编写application.properties编写User类编写controller编写service测试思考为什么键值要序序列化呢?​ 不同平台之间的数据传输,深拷贝,浅拷贝,如果不采用序列化,很容易在传输过程中出现各种错误,无法正常使用Redis的序列化到底是什么?​ 简单的是说 就是 key ..._spring boot redis 查询序列化key

随便推点

JavaSE基础知识(十三)--Java的数组以及数组的初始化_int a1=a[rand.nextint(a.length)];-程序员宅基地

文章浏览阅读1.1k次。Java SE 是什么,包括哪些内容(十三)?本文内容参考自Java8标准数组是相同类型的,用一个标识符名称封装到一起的一个对象引用序列或基本数据类型序列,数组是通过方括号下标操作符[ ]来定义和使用的,要定义一个数组,只需要在类型后面加上一个[ ],并取一个合适的标识符名称即可。上面的内容总共体现在三个方面:⑴、数组内的数据类型必须是同一类型,也就是说在一个数组内不能同时存储不同数据类型..._int a1=a[rand.nextint(a.length)];

计算机专业2016高考录取分数线,华南师范大学计算机类专业2016年在广东理科高考录取最低分数线...-程序员宅基地

文章浏览阅读129次。类似问题答案华南师范大学计算机类专业2015年在广东理科高考录取最低分数线学校 地 区 专业 年份 批次 类型 分数 华南师范大学 广东 计算机类 2015 一批 理科 612 学校 地 区 专业 年份 批次 类型 分数 华南师范大学 广东 计算机类 2016 一批 理科 563 华南师范大学 广东 计算机类 2016 一批 理科 563 华南师范大学 广东 计算机类 2015 一批 理科 612..._华南师范大学广东2016各专业分数线

arm-linux-gnueabihf opencv,opencv3.4.9 + armv7 + arm-linux-gnueabihf交叉编译-程序员宅基地

文章浏览阅读249次。mac上编译 arm linux gnueabi交叉编译工具链toolchaincrosstool-ng 编译和安装 交叉编译工具下载: git clone [email protected]:secularbird/crosstool-ng.git 切换到mac编译分支 git ...Windows平台交叉编译Arm Linux平台的QT5&period;7库1.准备交叉编译环境 环境说..._gcc-arm-linux-gnueabihf armv7l

mysql数据库dao模式_mysql中DAO模式-程序员宅基地

文章浏览阅读591次。JDBC封装优点:隔离细节降低代码间耦合性提高代码可扩展性和维护性附注:DAO模式提供了访问关系型数据系统所需操作的接口,将数据访问和业务逻辑分开,对上层提供面向对象的数据访问接口.DAO模式实现两层分离:代码间分工明确,数据访问层代码不影响业务逻辑层代码,这也符合单一职能原则,降低了耦合度,提高了代码的可复用性。。隔离了不同的数据库的实现,采用面向接口编程,如果底层数据变化了,如mysql变成了..._mysqldao

Android对数据按照时间排序,Android实现数据按照时间排序-程序员宅基地

文章浏览阅读748次。经常遇见一个列表,两个接口的情况,两个接口属于两个不同的表数据,那么数据拼接回来之后,并不是按照时间排序的,看起来就相当混乱,所以记录一下如何对数据按照时间排序。步骤一:格式化日期public static Date stringToDate(String dateString) {ParsePosition position = new ParsePosition(0);SimpleDateFo..._安卓代码实现聊天记录根据时间排序

华硕固件默认ip,新路由3 newifi d2刷机刷华硕固件教程-程序员宅基地

文章浏览阅读4.9k次。新路由3默认的功能非常的少,所以不刷个好固件简直就是浪费硬件性能,恢复出厂后默认的路由器IP就是192.168.99.1。准备下面几个工具和固件上面工具准备好以后,下面开始刷机:一. 开启固件 SSH1、开启路由器,进入管理界面 (假设路由器 IP 地址是 192.168.99.1)2、 在浏览器中输入 http://192.168.99.1/newifi/ifiwen_hss.html 并进入3..._路由器刷华硕固件之后默认ip