操作系统课设——文件管理模拟系统C++

2024-06-08 1321阅读

操作系统课设——文件管理模拟系统C++

        可以看到文件命令是仿照Linux的,但是也就仿了一点点。所有代码都在一个cpp文件中(也没想到会写这么多,就没分开写了),代码总行数1800行左右,代码注释都是交给星火大模型弄的(老师要求要有详细注释,1800行太多啦,时间又赶,就交给人工智能啦),看了一下注释的基本没问题。好了下面是正文。

--------------

目录

1.概述

2.预备知识

2.1文件管理的主要功能

2.1.1文件存储空间的管理

2.1.2目录管理

2.1.3文件的读写管理

2.1.4文件的存取控制

2.2文件属性

2.3文件操作

2.3.1对文件记录的操作

2.3.2对文件自身的操作

2.4文件控制块(FCB)

2.5目录

2.5.1目录的功能

2.5.2目录的操作

2.5.3树形目录

3.系统设计

3.1用户的简单管理

3.2简单的内存管理

3.3较复杂的文件管理

3.3.1 FCB类

3.3.2文件(File)类

3.3.3目录(Directory)类

3.4命令函数

3.5其他函数申明

4.系统实现

4.1用户管理

4.2内存管理

4.3文件管理

4.4全局变量

4.5命令函数

4.6其他函数

4.7main函数

5.系统测试

5.1系统能否正常运行

5.2各项命令功能测试

5.2.1help

5.2.2useradd

5.2.3su

5.2.4useralt

5.2.5userdel

5.2.6touch

5.2.7echo

5.2.8cat

5.2.9rm

5.2.10mkdir

5.2.11mvdir

5.2.12cd

5.2.13alterf

5.2.14alterd

5.2.15chmodf

5.2.16chmodd

5.2.17ls

5.2.18ls -l

5.2.19ls -a

5.2.20exit

5.3内存管理测试

6.  结语


1.概述

    文件管理作为操作系统的一大基本功能,是实现程序和数据等信息存储的主要方式,因此文件管理系统也称为信息资源管理系统。文件管理要解决的问题是向用户提供一种简单便捷、统一的存取和管理信息的方法,同时要保证信息的安全性和共享性。本篇设计说明将通过使用C++语言结合Visual Studio 2019开发平台实现对文件管理系统的模拟,试图模拟出符合逻辑、拥有文件系统各项基本功能的系统。

2.预备知识

2.1文件管理的主要功能

    文件管理的主要功能分为文件存储管理、目录管理、文件的读写管理、文件的存取管理。

2.1.1文件存储空间的管理

一般而言,系统文件和用户文件放在可随机存取的磁盘上。对于用户而言没有经过任何管理的文件寻找和使用起来都很不便捷,十分低效。因而,需要有文件系统对许多文件以及文件的存储空间进行统一管理。主要任务就是为每个文件分配足够的存储空间,提高存储空间的利用率,提高文件的工作速度。

2.1.2目录管理

目录管理是为了用户能方便的找到所需文件,也能便于用户对文件的各种分类管理,通常会由系统为每个文件建立一个目录项。目录项包含文件名、文件属性、文件的物理位置等信息。

2.1.3文件的读写管理

读写作为文件的基本操作,能够根据用户的需求读取磁盘数据或向磁盘写入数据。在读操作中,用户需要提供文件名,文件系统通过检索文件目录找到该文件,并获取文件所在的物理位置;在写操作中,用户可以在目录下创建文件并写入信息,文件系统为该文件创建目录项,同时分配存储空间,保存物理位置、文件名的信息等。

2.1.4文件的存取控制

为保证文件内信息的安全性和共享性,文件系统必须严格控制文件的存取过程。这涉及到文件的权限管理。在Linux系统中主要有读、写、执行权限,Windows系统中的权限更为复杂,且各用户之间权限交叉程度大。

2.2文件属性

文件包含两部分内容:一是文件所包含的数据;二是文件所包含的自身说明信息,即属性。文件属性主要有以下几种:

(1)文件名。

(2)文件内部标识符。也就是一个编号,是系统内为每个文件创建的唯一标识符。

(3)文件的物理位置。

(4)文件的拥有者。

(5)文件的存取控制。这决定了系统中各种用户对该文件的权限。

(6)文件的类型。

(7)文件的长度。

(8)文件时间。如创建时间,最后一次修改时间等。

2.3文件操作

文件操作指文件向用户提供的各种接口。主要分为两大类:一是对文件记录的操作;二是对文件自身的操作。

2.3.1对文件记录的操作

(1)检索记录。

(2)插入记录。

(3)修改记录。

(4)删除记录。

2.3.2对文件自身的操作

(1)创建文件。创建文件时,系统要为其分配存储空间,并建立一个目录项。

(2)删除文件。删除时,系统将该文件的目录项置空,然后回收存储空间。

(3)读文件。

(4)写文件。

(5)设置文件的读/写位置。对文件进行读/写操作之前,需要对文件的读/写

(6)截断文件。如果一个文件的内容已经没用,虽然可以先删除文件在建立一个新的文件,但如果文件名及其属性并没有发生变化,也可以截断文件。即将文件的长度设为0,或者放弃原有的文件内容。

(7)打开文件。

(8)关闭文件。

(9)获取文件属性。

(10)设置文件的属性。用户可以改变文件的存取控制权限等。

2.4文件控制块(FCB)

为了能够对文件进行正确的存取,必须为文件设置一种用于描述和控制文件的数据结构——文件控制块(File Control Block,FCB)。文件控制块的有序集合即为文件目录,文件控制块就是其中的目录项。该数据结构包含以下内容:

(1)文件名。

(2)文件物理位置。

(3)文件逻辑位置。

(4)文件的存取权限。

(5)核准用户的存取权限。

(6)一般用户的存取权限。

(7)文件的建立日期和时间。

(8)文件的修改日期和时间。

(9)当前使用信息。包括当前已打开文件的进程数、文件是否被进程锁住等。

2.5目录

目录的存在主要是方便通过用户给的文件名找到文件。

2.5.1目录的功能

目录的功能如下:

(1)实现按名存取。用户只需要给出文件名,即可对文件进行各种操作。

(2)提高检索速度。合理地组织目录结构,加快文件检索速度。

(3)允许文件同名。便于用户能够按照自身的习惯来命名和使用文件。

(4)文件共享。一个文件能够被多个用户使用。这要求文件系统有合理的文件权限管理。

2.5.2目录的操作

目录有以下操作:

(1)目录创建。目录就是多个文件控制块的集合,通常以文件的形式存储在外部存储器上,目录创建就是在外存上建立一个目录文件用以存储文件的FCB。

(2)目录删除。

(3)目录检索。当用户按名存取文件时,文件系统能够通过对目录进行检索找到对应文件。

(4)目录的打开与关闭。

2.5.3树形目录

    在树形目录中,有一个主目录和许多分目录,分目录不但可以包括文件,还可以包含下一级目录,这样扩展下去就形成了多级层次目录,这样也方便地制定保护文件的存取权限。主目录是树的根节点,文件时树的叶子节点,其他分目录是树的分支节点。在树形目录中通过路径名来访问文件,在该通路上的所有文件名和目录名用“\”连接起来,构成该文件的路径名。通常树形目录会为每个用户设置一个当前目录,也称工作目录。树形目录能够方便用户查找文件,又可以把不同类型的文件进行分类,同时,只要在不同的分目录中,文件命名可以相同。

3.系统设计

       为构建符合逻辑,拥有各项文件系统基本功能的系统,我仿照linux中对文件管理的操作,在系统设计方面提出了四大模块:用户管理、内存管理、文件管理、命令函数。它们分别实现对用户的简单管理,对内存的简单管理、对文件的较复杂的管理和对系统的操作命令。

3.1用户的简单管理

       在这一模块中,定义了一个用户类(User),用户的属性只有简单的两个,即用户名和密码。用户的操作有获取用户名、获取密码、设置用户名、设置密码。为实现对用户的简单管理,我在此基础上又新增加了一个类专门用来管理用户信息,命名为UserList,实现添加用户,删除用户,查找用户等功能。这两个类的设计如下:

// 用户类
class User
{
private:
 string name;
 string passwd;
public:
 User() {}
 User(string name_c, string passwd_c)
 {
  this->name = name_c;
  this->passwd = passwd_c;
 }
 ~User() {}
 void operator () (string name, string passwd) { this->name = name; this->passwd = passwd; }
 string GetName() { return this->name; }
 string GetPasswd() { return this->passwd; }
 void SetName(string name) { this->name = name; }
 void SetPasswd(string passwd) { this->passwd = passwd; }
};
// 实现简单的用户管理
class UserList
{
public:
 bool AddUser(User u); // 添加用户
 bool DelUser(User u); // 删除用户
 bool DelUser(string name);
 short FindUser(User u); // 查找用户,找到则返回所在用户表中的位置
 short FindUser(string name); // 查找用户,找到则返回所在用户表中的位置
 void ViewUser(); // 查看用户
 bool Signin(string name, string pw); // 用户登录
 User GetUser(string name);
private:
 bool FindUserByPw(string passwd, int i); // 密码对比
 vector users; // 用户表
 static short n; // 记录UserList实例化数
};

3.2简单的内存管理

       在内存管理这一模块中,我是以向系统申请一块能够存储1024个int整形数组,通过对数组中的值赋0或者1来表示文件在系统中的位置和大小,以此构建一个简单的虚拟的内存管理。其中0表示该内存为空,1表示该内存已占用。值得注意的是用户的创建不占用内存。内存管理类命名为Location,有申请内存、获取地址和回收内存的功能,具体类设计如下:

constexpr auto MAX_MEMORY = 1024;
// 内存管理
class Location
{
private:
 static int maxLocation[MAX_MEMORY];
 int location = 0;
public:
 Location():location(0) {}
 Location(int size);
 bool SetLocation(int size); // 申请内存
 int GetLocation() { return location; } // 获取地址
 void Recycle(int size);  // 回收内存
};

3.3较复杂的文件管理

       在这一模块中,为了能够较规范的实现文件管理,我定义了3个类:FCB、文件(File)、目录(Directory)。权限控制仿照Linux给出了3种权限,分别是:读(read)、写(write)、执行(execute),用整型表示为1、2、4。

3.3.1 FCB类

       FCB的主要功能是存储除了文件内容外的文件所有信息,以及能够对已修改的文件进行信息更新,同时还提供了信息视图。

       在FCB中,有如下属性:

  1. 文件名(fname);
  2. 文件位置(location);
  3. 文件大小(size);
  4. 属主用户(mUser);
  5. 主用户权限(masterUser);
  6. 其他用户权限(otherUser);
  7. 文件建立时间(createTime);
  8. 文件修改时间(alterTime)。

功能有:

  1. 创建FCB(SetFCB)
  2. 查看FCB视图(ViewFCB)
  3. 更新命名(UpdateName)
  4. 更新文件内容大小(UpdateFCSize)
  5. 更新权限(UpdateRight)
  6. 更新修改时间(UpdateaTime)
  7. 获取文件名(GetName)
  8. 获取内容大小(GetFCSize)
  9. 获取主用户信息(GetmUser)

具体类设计如下:

class FCB
{
private:
 string fname; // 文件名
 Location location; // 文件位置
 int size = 0;  // 文件大小
 User mUser;  // 属主用户
 int masterUser = 0; // 主用户权限
 int otherUser = 0; // 其他用户权限
 string createTime; // 文件建立时间
 string alterTime; // 文件修改时间
public:
 FCB() {}
 FCB(string name, User user);
 void SetFCB(string name, User user); // 创建FCB
 void ViewFCB(); // 查看FCB视图
 void UpdateName(string name); // 更新命名
 void UpdateFCSize(int size); // 更新文件内容大小
 void UpdateRight(int m , int o); // 更新权限
 void UpdateaTime(); // 更新修改时间
 string GetName(); // 获取文件名
 int GetFCSize(); // 获取内容大小
 User GetmUser(); // 获取主用户信息
};
3.3.2文件(File)类

       该类主要功能是实现文件的创建,文件内容的增删改查,文件权限的修改等,每一个实例对象都包含一个FCB,换句话说FCB是保存在文件中的。文件的内容用一个string类型变量存储。

       具体类设计如下:

class File
{
private:
 string fcontent;
 FCB fcb;
public:
 File();
 bool CreateFile(string fname, User user); // 创建文件
 void View() { fcb.ViewFCB(); } // 文件视图
 void WriteFileC(string content); // 增
 void DelFileC(); // 删
    void AlterFileC(string content); // 改
 void ReadFileC(); // 查
 void ExecuteFile(); // 执行
 void AlterFileR(int mright, int oright ); // 修改权限
 string GetFName(); // 获取命名
 User GetmUser(); // 获取属主用户
 void AlterFName(string name); // 更改文件名
};
3.3.3目录(Directory)类

       目录类需要实现的功能是存储目录的所有信息,包含目录下存在的目录和文件,以此实现树形目录结构的管理,还有创建、添加、删除等各项功能。值得注意的是目录类中所包含的目录和文件是以目录名和文件名存储在一个string的向量中的,在通过路径查找目录或者文件时,会通过存储在向量中的文件名和目录名查找该目录下是否存在,不存储在则显示无此文件或目录。该类主要是提供有关目录的基础操作。

       目录类的具体定义如下:

class Directory
{
private:
 string dname;
 int cnum; // 记录目录数量
 int fnum; // 记录文件数量
 int size; // 目录大小
 int masterUser = 0; // 主用户权限
 int otherUser = 0; // 其他用户权限
 string createTime; // 创建时间
 string alterTime; // 修改时间
 Location location; // 在虚拟内存中的位置
 User duser; // 目录所属用户
 string fcontent; // 父目录
 vector contents; // 子目录
 vector files; // 子文件
public:
 Directory();
 Directory(string name, User user);
 ~Directory();
 bool Create(string name, User user); // 创建目录
 void Delete(); // 删除目录
 void AlterDName(string name); // 更改目录名
 bool AlterDRight(int m, int o); // 更改目录权限
 void Open(); // 查看目录下包含的目录和文件,对应ls操作
 bool AddContent(const string& content); // 向目录中添加目录(名)
 bool DelContent(const string& content); // 向目录中删除目录(名)
 bool AddFile(string& filename); // 向目录中添加文件(名)
 bool AlterFileName(string& oldName, string& newName, File& file); // 在目录中更改包含文件的文件名
 bool AlterContentName(string& oldName, string& newName, Directory& content);   // 在目录汇总更改包含目录的目录名
 bool DelFile(string name); // 向目录中删除文件(名)
 int FindFile(string name); // 查找包含文件
 int FindContent(string name); // 查找包含目录
 string GetDName(); // 获取目录名
 string GetFName(int i); // 获取文件名
 string GetUName(); // 获取主用户名
 int GetMRight(); // 获取主用户权限
 int GetORight(); // 获取其他用户权限
 vector GetFiles(); // 获取包含文件向量
 vector GetContents(); // 获取包含目录向量
 void Recycle(); // 回收目录所占用空间
 void View(); // 目录视图
};

3.4命令函数

       对该文件系统的命令操作以仿照Linux为主,提供了ls、useradd、su等经典操作。各函数声明如下:

// 命令
bool ls(); // 查看当前目录
bool useradd(); // 添加用户
bool su(string name); // 登录用户
bool userdel(string name); // 删除用户
bool useralt(); // 修改用户信息
bool touch(string name); // 创建文件
bool cat(string name); // 读取文件
bool echo(string name); // 打开并编辑文件
bool rm(string name); // 删除文件
bool mkdir(string name); // 创建目录
bool mvdir(string name); // 删除目录
bool cd(string path); // 打开目录
void ls_l(); // 查看当前目录详细信息
bool alter_f(string name); // 更改文件名
bool alter_d(string name); // 更改目录名
bool chmod_f(string name); // 更改文件的权限
bool chmod_d(string name); // 更改目录的权限
void ls_a(); // 查看所有目录和文件的详细信息
void help(); // 获取所有命令信息

3.5其他函数申明

       这里主要包括本地时间获取函数、控制台输出美化函数、分割字符创等函数,具体声明如下:

// 获取控制台句柄
const HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
// 获取当地时间
string GetTime();
// 隐藏控制台光标
void HideConsoleCursor();
// 显示控制台光标
void ShowConsoleCursor();
// uFore: 前景色,uBack: 背景色
void SetColor(UINT uFore, UINT uBack);
// 指定前景色和背景色,缓慢输出
void ccout(const char* c, UINT uFore = 7, UINT uBack = 0, UINT sleeptime = 0);
// 输出命令行头
void PutHeadInCommandLine();
// 权限检查
int RightCheck();
// 分割字符串
vector split(string str, string pattern);

4.系统实现

       引入的头文件:

#include 
#include  // I love string!!!!
#include 
#include 
#include 
using namespace std;

4.1用户管理

       用户管理代码实现如下:

// Class: UserList
short UserList::n = 0;
// 添加用户
bool UserList::AddUser(User u)
{
 int i = FindUser(u); // 查找用户名
 if (i == -1) // 如果用户不存在,则添加用户
 {
  users.push_back(u); // 将用户添加到用户列表中
  n++; // 用户数量加1
  return true; // 返回添加成功
 }
 return false; // 返回添加失败,用户已存在
}
// 删除用户
bool UserList::DelUser(User u)
{
 short i = FindUser(u); // 查找用户名
 if (i != -1) // 如果用户存在
 {
  for (vector::iterator it = users.begin(); it != users.end(); it++) // 遍历用户列表
  {
   if ((*it).GetName() == u.GetName()) // 如果找到匹配的用户
   {
    users.erase(it); // 从用户列表中删除该用户
    return true; // 返回删除成功
    break;
   }
  }
  n--; // 用户数量减1
  return true; // 返回删除成功
 }
 return false; // 返回删除失败,用户不存在
}
bool UserList::DelUser(string name)
{
 short i = FindUser(name); // 查找用户名
 if (i != -1) // 如果用户存在
 {
  for (vector::iterator it = users.begin(); it != users.end(); it++) // 遍历用户列表
  {
   if ((*it).GetName() == name) // 如果找到匹配的用户
   {
    users.erase(it); // 从用户列表中删除该用户
    return true; // 返回删除成功
    break;
   }
  }
  n--; // 用户数量减1
  return true; // 返回删除成功
 }
 return false; // 返回删除失败,用户不存在
}
// 查找用户,找到则返回所在用户表中的位置
short UserList::FindUser(User u)
{
 int i = 0;
 for (vector::iterator it = users.begin(); it != users.end(); it++) // 遍历用户列表
 {
  if ((*it).GetName() == u.GetName()) // 如果找到匹配的用户
  {
   return i; // 返回用户在列表中的位置
  }
  i++; // 继续查找下一个用户
 }
 return -1; // 返回-1,表示未找到匹配的用户
}
// 查找用户,找到则返回所在用户表中的位置
short UserList::FindUser(string name)
{
 int i = 0;
 for (vector::iterator it = users.begin(); it != users.end(); it++) // 遍历用户列表
 {
  if ((*it).GetName() == name) // 如果找到匹配的用户
  {
   return i; // 返回用户在列表中的位置
  }
  i++; // 继续查找下一个用户
 }
 return -1; // 返回-1,表示未找到匹配的用户
}
// 密码对比
bool UserList::FindUserByPw(string passwd, int i)
{
 if (n == 0) // 如果用户列表为空
 {
  return false; // 返回false,表示未找到匹配的用户
 }
 for (i; i GetDName())
                    {
                        // 更新dlist目录向量中的一个目录下的所含文件名向量
                        it->DelFile(name); 
                        break;
                    }
                }
                return true;
            }
            else
            {
                // 输出权限不足的错误信息
                ccout("权限过低!\n", 12, 0);
                return false;
            }
        }
    }
    // 输出未找到该文件的错误信息
    ccout("未找到该文件!\n", 12, 0);
    return false;
}
// 创建目录函数,接收一个字符串参数name,表示要创建的目录名称
bool mkdir(string name) // 创建目录
{
    Directory d; // 创建一个Directory对象d
    bool b = d.Create(name, *curuser); // 调用Directory对象的Create方法,传入目录名称和当前用户,返回是否创建成功
    if (b) // 如果创建成功
    {
        dlist.push_back(d); // 将创建的目录添加到dlist向量中
        curdirectory->AddContent(name); // 将创建的目录添加到当前目录的内容列表中
        for (vector::iterator it = dlist.begin(); it != dlist.end(); it++) // 遍历dlist向量
        {
            if (curdirectory->GetDName() == it->GetDName()) // 如果当前目录的名称与遍历到的目录的名称相同
            {
                it->AddContent(name); // 更新遍历到的目录的内容列表中,添加新创建的目录名称
                break; // 跳出循环
            }
        }
        return true; // 返回创建成功
    }
    else // 如果创建失败
    {
        ccout("创建失败!\n", 12, 0); // 输出创建失败的信息
        return false; // 返回创建失败
    }
}
bool mvdir(string name) // 删除目录
{
    // 遍历dlist向量
    for (vector::iterator it1 = dlist.begin(); it1 != dlist.end(); it1++) 
    {
        // 查找目录
        if ((*it1).GetDName() == name) 
        {
            // 权限判断
            if ((*it1).GetUName() == curuser->GetName() || curuser->GetName() == "root") 
            {
                // 回收目录
                it1->Recycle();
                // 从dlist中删除目录
                dlist.erase(it1);
                // 从当前目录的内容列表中删除目录
                curdirectory->DelContent(name);
                // 遍历dlist向量
                for (vector::iterator it = dlist.begin(); it != dlist.end(); it++) 
                {
                    // 如果当前目录的名称与遍历到的目录的名称相同
                    if (curdirectory->GetDName() == it->GetDName())
                    {
                        // 更新dlist目录向量中的一个目录下的所含目录名向量
                        it->DelContent(name); 
                        break;
                    }
                }
                return true;
            }
            else
            {
                // 输出权限过低的信息
                ccout("权限过低!\n", 12, 0);
                return false;
            }
        }
    }
    // 输出未找到该目录的信息
    ccout("未找到该目录!\n", 12, 0);
    return false;
}
bool cd(string path) // 打开目录
{
    // 如果路径长度为1且第一个字符为'\\',则打开根目录
    if (path.length() == 1 && path[0] == '\\') 
    {
        *curdirectory = dlist[0]; 
        return true;
    }
    // 将路径按照'\\'分割成字符串向量vpath
    vector vpath = split(path, "\\");
    Directory curd = *curdirectory;
    // 如果路径的第一个字符不为'\\',则在当前目录下查找,即通过相对路径查找
    if (path[0] != '\\') 
    {
        for (unsigned int i = 0; i FindContent(vpath[i]) != -1) 
            {
                // 遍历dlist向量
                for (vector::iterator it = dlist.begin(); it != dlist.end(); it++) 
                {
                    // 查找目录
                    if ((*it).GetDName() == vpath[i]) 
                    {
                        // 更新当前目录
                        *curdirectory = *it; 
                        break;
                    }
                }
            }
            // 在当前目录下查找是否包含输入的第一个文件名
            else if (curdirectory->FindFile(vpath[i]) != -1 && i == vpath.size() - 1) 
            {
                cat(curdirectory->GetFName(curdirectory->FindFile(vpath[i])));
            }
            // 如果未找到指定目录,则返回false
            else
            {
                *curdirectory = curd;
                ccout("未找到指定目录!\n", 12, 0);
                return false;
            }
        }
        return true;
    }
    // 如果路径的第一个字符为'\\',则在绝对路径下查找
    else if (path[0] == '\\') 
    {
        // 将当前目录设置为根目录
        *curdirectory = dlist[0];
        // 移除空向量值
        vpath.erase(vpath.begin()); 
        for (unsigned int i = 0; i FindContent(vpath[i]) != -1) 
            {
                // 遍历dlist向量
                for (vector::iterator it = dlist.begin(); it != dlist.end(); it++) 
                {
                    // 查找目录
                    if ((*it).GetDName() == vpath[i]) 
                    {
                        // 更新当前目录
                        *curdirectory = *it; 
                        break;
                    }
                }
            }
            // 在当前目录下查找是否包含输入的第一个文件名
            else if (curdirectory->FindFile(vpath[i]) != -1 && i == vpath.size() - 1) 
            {
                cat(curdirectory->GetFName(curdirectory->FindFile(vpath[i])));
            }
            // 如果未找到指定目录,则返回false
            else
            {
                ccout("未找到指定目录!\n", 12, 0);
                return false;
            }
        }
        return true;
    }
    // 如果路径不符合以上两种情况,则返回false
    else
        return false;
}
void ls_l()
{
    // 获取当前目录下的文件列表
    vector files = curdirectory->GetFiles();
    // 获取当前目录下的内容列表(包括目录和文件)
    vector contents = curdirectory->GetContents();
    // 输出表头信息
    ccout("目录名 | 位置 | 大小 | 目录数量 | 文件数量 | 属主用户 | 父目录 | 主用户权限 | 其他用户权限 | 创建时间 | 修改时间
", 6, 0);
    // 遍历内容列表,查找并显示目录信息
    for (vector::iterator itc = contents.begin(); itc != contents.end(); itc++)
    {
        for (vector::iterator itl = dlist.begin(); itl != dlist.end(); itl++)
        {
            // 如果内容列表中的项与目录列表中的项相同,则显示目录信息并跳出循环
            if (itc->compare(itl->GetDName()) == 0)
            {
                itl->View();
                break;
            }
        }
    }
    // 输出文件列表的表头信息
    ccout("文件名 | 位置 | 大小 | 属主用户 | 主用户权限 | 其他用户权限 | 创建时间 | 修改时间
");
    // 遍历文件列表,查找并显示文件信息
    for (vector::iterator itf = files.begin(); itf != files.end(); itf++)
    {
        for (vector::iterator itl = flist.begin(); itl != flist.end(); itl++)
        {
            // 如果文件列表中的项与文件列表中的项相同,则显示文件信息并跳出循环
            if (itf->compare(itl->GetFName()) == 0)
            {
                itl->View();
                break;
            }
        }
    }
}
bool alter_f(string name) // 更改文件名
{
    vector files = curdirectory->GetFiles(); // 获取当前目录下的所有文件名
    for (vector::iterator itf = files.begin(); itf != files.end(); itf++) // 遍历所有文件名
    {
        if (itf->compare(name) == 0) // 如果找到了要更改的文件名
        {
            for (vector::iterator itl = flist.begin(); itl != flist.end(); itl++) // 遍历所有文件对象
            {
                if (itf->compare(itl->GetFName()) == 0) // 如果找到了对应的文件对象
                {
                    if (itl->GetmUser().GetName() == curuser->GetName() || curuser->GetName() == "root") // 判断权限
                    {
                        string newname; // 新的文件名
                        ccout("新的文件名:", 3, 0); // 输出提示信息
                        getline(cin, newname); // 从输入流中读取新的文件名
                        curdirectory->AlterFileName(*itf, newname, *itl); // 调用函数更改文件名
                        return true; // 更改成功,返回true
                    }
                    else
                    {
                        ccout("权限过低!\n", 12, 0); // 权限不足,输出提示信息
                        return false; // 更改失败,返回false
                    }
                }
            }
        }
    }
    ccout("未找到文件!\n", 12, 0); // 未找到文件,输出提示信息
    return false; // 更改失败,返回false
}
bool alter_d(string name) // 更改目录名
{
    // 获取当前目录下的所有内容
    vector contents = curdirectory->GetContents();
    // 遍历所有内容
    for (vector::iterator itc = contents.begin(); itc != contents.end(); itc++)
    {
        // 如果找到了要更改的目录名
        if (itc->compare(name) == 0)
        {
            // 遍历所有目录对象
            for (vector::iterator itl = dlist.begin(); itl != dlist.end(); itl++)
            {
                // 如果找到了对应的目录对象
                if (itc->compare(itl->GetDName()) == 0)
                {
                    // 判断权限,如果当前用户是该目录的所有者或者当前用户是root用户
                    if (itl->GetUName() == curuser->GetName() || curuser->GetName() == "root") 
                    {
                        // 输入新的目录名
                        string newname;
                        ccout("新的目录名:", 3, 0);
                        getline(cin, newname);
                        // 调用函数更改目录名
                        curdirectory->AlterContentName(*itc, newname, *itl);
                        // 更改成功,返回true
                        return true;
                    }
                    else
                    {
                        // 权限不足,输出提示信息
                        ccout("权限过低!\n", 12, 0);
                        // 更改失败,返回false
                        return false;
                    }
                }
            }
        }
    }
    // 未找到目录,输出提示信息
    ccout("未找到目录!\n", 12, 0);
    // 更改失败,返回false
    return false;
}
bool chmod_f(string name) // 更改文件的权限
{
    // 获取当前目录下的所有文件名
    vector files = curdirectory->GetFiles();
    // 遍历所有文件名
    for (vector::iterator itf = files.begin(); itf != files.end(); itf++)
    {
        // 如果找到了要更改权限的文件名
        if (itf->compare(name) == 0)
        {
            // 遍历所有文件对象
            for (vector::iterator itl = flist.begin(); itl != flist.end(); itl++)
            {
                // 如果找到了对应的文件对象
                if (itf->compare(itl->GetFName()) == 0)
                {
                    // 判断权限是否允许修改
                    if (itl->GetmUser().GetName() == curuser->GetName() || curuser->GetName() == "root") 
                    {
                        // 输入新的权限
                        string newright;
                        ccout("输入权限:", 3, 0);
                        getline(cin, newright);
                        // 检查输入的权限格式是否正确
                        if (newright.length() == 2 && newright[0] - '0' GetContents();
    // 遍历所有内容
    for (vector::iterator itc = contents.begin(); itc != contents.end(); itc++)
    {
        // 如果找到了要修改权限的目录名
        if (itc->compare(name) == 0)
        {
            // 遍历所有目录对象
            for (vector::iterator itl = dlist.begin(); itl != dlist.end(); itl++)
            {
                // 如果找到了要修改权限的目录对象
                if (itc->compare(itl->GetDName()) == 0)
                {
                    // 判断当前用户是否有权限修改该目录的权限
                    if (itl->GetUName() == curuser->GetName() || curuser->GetName() == "root") 
                    {
                        // 输入新的权限值
                        string newright;
                        ccout("输入权限:", 3, 0);
                        getline(cin, newright);
                        // 判断输入的权限格式是否正确
                        if (newright.length() == 2 && newright[0] - '0' View(); // 调用目录对象的View方法,显示详细信息
    }
    ccout("文件名 | 位置 | 大小 | 属主用户 | 主用户权限 | 其他用户权限 | 创建时间 | 修改时间
"); // 输出文件表头
    for (vector::iterator it = flist.begin(); it != flist.end(); it++) // 遍历文件列表
    {
        it->View(); // 调用文件对象的View方法,显示详细信息
    }
}
void help() // 获取所有命令信息
{
    ccout("ls : 查看当前目录\n", 11, 0);
    ccout("  参数有:\n\t-l + [directory_name]: 查看当前目录详细信息\n\t-a : 查看所有目录和文件的详细信息\n", 11, 0);
    ccout("useradd + [user_name]: 添加用户\n", 11, 0);
    ccout("userdel + [user_name]: 删除用户\n", 11, 0);
    ccout("useralt : 修改当前用户的信息\n", 11, 0);
    ccout("touch + [file_name]: 创建文件\n", 11, 0);
    ccout("cat + [file_name]: 读取文件\n", 11, 0);
    ccout("echo + [file_name]: 打开并编辑文件\n", 11, 0);
    ccout("rm + [file_name]: 删除文件\n", 11, 0);
    ccout("mkdir + [directory_name]: 创建目录\n", 11, 0);
    ccout("mvdir + [directory_name]: 删除目录\n", 11, 0);
    ccout("cd + [path]: 打开目录或文件\n", 11, 0);
    ccout("alterf + [file_name]: 更改文件名\n", 11, 0);
    ccout("alterd + [directory_name]: 更改目录名\n", 11, 0);
    ccout("chmodf + [file_name]: 更改文件权限\n", 11, 0);
    ccout("chmodd + [directory_name]: 更改目录权限\n", 11, 0);
    ccout("exit: 退出系统\n", 11, 0);
}

4.6其他函数

       其他函数代码实现如下:

// 获取当前时间的函数
string GetTime()
{
    time_t timep;
    time(&timep); // 获取当前时间
    string t1 = ctime(&timep); // 将时间转换为字符串格式
    t1.pop_back(); // 删除最后一个字符 '\n'
    return t1;
}
// 隐藏控制台光标的函数
void HideConsoleCursor()
{
    CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
    SetConsoleCursorInfo(handle, &cursor_info);
}
// 显示控制台光标的函数
void ShowConsoleCursor()
{
    CONSOLE_CURSOR_INFO cursor_info = { 1, 1 };
    SetConsoleCursorInfo(handle, &cursor_info);
}
// 设置控制台文本颜色的函数
void SetColor(UINT uFore, UINT uBack)
{
    SetConsoleTextAttribute(handle, uFore + uBack * 0x10);
}
// 输出带颜色和延时的字符串的函数
void ccout(const char* c, UINT uFore, UINT uBack, UINT sleeptime)
{
    SetColor(uFore, uBack); // 设置文本颜色
    if (sleeptime == 0)
    {
        cout GetName()) // 如果当前目录属于当前用户
    {
        return curdirectory->GetMRight(); // 返回当前用户的读写权限
    }
    else
        return curdirectory->GetORight(); // 否则返回其他用户的读写权限
}
// 将字符串按照指定模式分割成字符串数组的函数
vector split(string str, string pattern)
{
    string::size_type pos;
    vector result; // 存储分割后的字符串数组
    str += pattern; // 扩展字符串以方便操作
    unsigned int size = str.size(); // 获取字符串长度
    for (unsigned int i = 0; i  pw;
 uroot.SetPasswd(pw);
 Sleep(1000);
 ccout("初始化用户列表...\n", 2);
 ulist.AddUser(uroot);
 Sleep(1000);
 ccout("初始化根目录...\n", 2);
 Directory rootdirectory;
 rootdirectory.Create("\\", uroot);
 dlist.push_back(rootdirectory);
 Sleep(1000);
 ccout("初始化home目录和root目录...\n", 2);
 *curdirectory = rootdirectory;
 Directory droot("root", uroot), dhome("home", uroot);
 curdirectory->AddContent(droot.GetDName());
 curdirectory->AddContent(dhome.GetDName());
 dlist[0].AddContent(droot.GetDName());
 dlist[0].AddContent(dhome.GetDName());
 dlist.push_back(droot);
 dlist.push_back(dhome);
 Sleep(1000);
 ccout("系统初始化完成!\n", 2);
        // 注册用户
 ccout("注册用户:\n", 3, 0, 20);
 string uname, upw;
 ccout("\t用户名:", 3, 0);
 cin >> uname;
 ccout("\t密码:", 3, 0);
 cin >> upw;
 cout GetName().c_str(), 14, 0, 20);
 ccout("登录本系统!\n", 3, 0, 20);
 *curdirectory = u1directory;
        // 进入命令行循环,处理用户输入的命令
 ccout("\t\t\t\t|        文件管理系统         |\n", 14, 8, 20);
 vector op;
 string s = "";
 getline(cin, s);
 s.clear();
 while (1)
 {
  PutHeadInCommandLine();
  getline(cin, s);
  op = split(s, " ");
  int size = op.size(); // 记录命令参数
  switch (size)
  {
  case(1):
   if (op[0] == "ls")
   {
    ls();
    break;
   }
   if (op[0] == "useradd")
   {
    useradd();
    getline(cin, s);
    break;
   }
   if (op[0] == "useralt")
   {
    useralt();
    getline(cin, s);
    break;
   }
   if (op[0] == "help")
   {
    help();
    break;
   }
   if (op[0] == "exit")
   {
    return 0;
   }
  case(2):
   if (op.size() != 2)
   {
    break;
   }
   if (op[0] == "userdel")
   {
    userdel(op[1]);
    break;
   }
   if (op[0] == "su")
   {
    su(op[1]);
    getline(cin, s);
    break;
   }
   if (op[0] == "touch")
   {
    touch(op[1]);
    break;
   }
   if (op[0] == "echo")
   {
    echo(op[1]);
    break;
   }
   if (op[0] == "cat")
   {
    cat(op[1]);
    break;
   }
   if (op[0] == "rm")
   {
    rm(op[1]);
    break;
   }
   if (op[0] == "mkdir")
   {
    mkdir(op[1]);
    break;
   }
   if (op[0] == "mvdir")
   {
    mvdir(op[1]);
    break;
   }
   if (op[0] == "mvdir")
   {
    mvdir(op[1]);
    break;
   }
   if (op[0] == "cd")
   {
    cd(op[1]);
    break;
   }
   if (op[0] == "ls")
   {
    if (op[1] == "-l")
    {
     ls_l();
     break;
    }
    if (op[1] == "-a")
    {
     ls_a();
     break;
    }
   }
   if (op[0] == "alterf")
   {
    alter_f(op[1]);
    break;
   }
   if (op[0] == "alterd")
   {
    alter_d(op[1]);
    break;
   }
   if (op[0] == "chmodf")
   {
    chmod_f(op[1]);
    break;
   }
   if (op[0] == "chmodd")
   {
    chmod_d(op[1]);
    break;
   }
  default:
   break;
  }
  op.clear();
  s.clear();
 }
 delete curdirectory, curuser;
 return 0;
}

5.系统测试

       测试的内容是系统是否正常运行,各种命令是否实现,内存的管理是否如期运行。

5.1系统能否正常运行

       编译运行结果:

操作系统课设——文件管理模拟系统C++

       输入1:

操作系统课设——文件管理模拟系统C++

输入用户名dong524和密码1:

操作系统课设——文件管理模拟系统C++

测试结果:运行正常

5.2各项命令功能测试

5.2.1help

       输入help:

操作系统课设——文件管理模拟系统C++

测试结果:运行正常

5.2.2useradd

       输入useradd:

操作系统课设——文件管理模拟系统C++

       输入用户名xxy,密码1:

操作系统课设——文件管理模拟系统C++

测试结果:运行正常

5.2.3su

       输入su xxy:

操作系统课设——文件管理模拟系统C++

       输入密码1:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常

5.2.4useralt

       输入useralt:

操作系统课设——文件管理模拟系统C++

       输入dong524和密码1:

操作系统课设——文件管理模拟系统C++

       权限测试成功,只有用户自己和root能够修改用户信息。再次输入useralt:

操作系统课设——文件管理模拟系统C++

       输入用户名xxy和密码11:

操作系统课设——文件管理模拟系统C++

       测试结果:运行成功。

5.2.5userdel

       输入userdel dong524:

操作系统课设——文件管理模拟系统C++

       权限测试成功,继续输入userdel xxy:

操作系统课设——文件管理模拟系统C++

       权限测试成功。选择登录到root用户,再输入userdel xxy:

操作系统课设——文件管理模拟系统C++

       再选择登录xxy,查看是否已经删除:

操作系统课设——文件管理模拟系统C++

       测试结果:运行成功。

5.2.6touch

       输入touch one:

操作系统课设——文件管理模拟系统C++

       输入ls查看当前目录下的文件和目录,目录用&表示:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.7echo

       输入echo one:

操作系统课设——文件管理模拟系统C++

       输入Hello World!:

操作系统课设——文件管理模拟系统C++

       再次echo one:

操作系统课设——文件管理模拟系统C++

       输入This is a file,再输入echo one:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.8cat

       输入cat one:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.9rm

       输入rm one,再输入ls查看当前目录:

操作系统课设——文件管理模拟系统C++

       当前目录为空,删除成功。测试结果:运行正常。

5.2.10mkdir

       输入mkdir one,再输入ls查看当前目录:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.11mvdir

       输入mvdir one,在输入ls查看当前目录:

操作系统课设——文件管理模拟系统C++

       目录删除成功。

       测试结果:运行正常。

5.2.12cd

       输入cd \,打开根目录:

操作系统课设——文件管理模拟系统C++

       输入ls查看根目录,并打开其中一个目录(通过相对路径访问):

操作系统课设——文件管理模拟系统C++

       输入cd \home\dong524,即通过绝对路径访问:

操作系统课设——文件管理模拟系统C++

       在该目录下创建一个one文件,并用echo写入this is a file:

操作系统课设——文件管理模拟系统C++

       再输入cd one,即通过cd命令查看文件内容:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.13alterf

       输入alterf one,在输入one2:

操作系统课设——文件管理模拟系统C++

       输入ls查看当前目录:

操作系统课设——文件管理模拟系统C++

       文件改名成功。

       测试结果:运行正常。

5.2.14alterd

       先创建目录dir,再输入alterd dir,最后ls查看当前目录:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.15chmodf

       输入chmodf one2:

操作系统课设——文件管理模拟系统C++

       权限格式为master other,分别用一个数字表示,如77、75、55、44。输入77:

操作系统课设——文件管理模拟系统C++

       输入ls -l命令查看文件权限:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.16chmodd

       输入chmodd dir2,在输入权限77,ls -l查看详细信息:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.17ls

       输入ls查看当前目录,有&且颜色为黄色的表示目录,白色的表示文件:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.18ls -l

       输入ls -l查看当前目录下所有文件和目录的详细信息:

操作系统课设——文件管理模拟系统C++

       测试结果,运行正常。

5.2.19ls -a

       输入ls -a查看系统所有目录和文件的详细信息:

操作系统课设——文件管理模拟系统C++

       发现标题行与信息行未回车分离,修改代码。

操作系统课设——文件管理模拟系统C++

       再次运行系统,输入ls -a:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.2.20exit

       输入exit退出系统:

操作系统课设——文件管理模拟系统C++

       测试结果:运行正常。

5.3内存管理测试

       在本系统中申请的1024个int型数组内存中只会存储目录名、文件名和文件内容,且都是以大小的形式将数组内存赋值为1。在申请内存时location类会从头查找maxLocation数组中第一个为0的位置,再往后查看为0的数量是否符合申请的数量,符合就将这一段全部复制为1,否则再次往后查找,直到找到符合申请的内存。系统初始化的过程中会创建4个目录,分别是根目录\、管理员目录root、用户目录home和新创建用户的主目录username,对应的大小都是目录名的大小。

       查看初始化系统后的内存情况,用ls -a:

操作系统课设——文件管理模拟系统C++

       可以看见目录的大小和在虚拟内存中的位置,这些目录都是紧挨着存放的。

       创建一个名为one的目录,该目录名大小为3。计算后可知道这个文件的位置将会是16。运行mkdir one,ls -a查看结果:

操作系统课设——文件管理模拟系统C++

       可以看到one目录的存储位置正如预期。

       现在创建一个名为file的文件,并通过echo将this is a file写入文件中。文件名大小加上信息长度等于18,那么这个文件在内存中的位置为19,大小为18。运行touch file,echo file this is a file,ls -a查看运行结果:

操作系统课设——文件管理模拟系统C++

       可以看到文件大小和位置正如预期。再创建一个文件查看该文件的位置是否等于19+18=37:操作系统课设——文件管理模拟系统C++

       可以看到新创建的文件dong的位置是37。

       内存管理测试成功,所有代码都如期执行。至此,整个系统测试完毕,系统运行良好,各功能均已实现,文件管理系统真正落成!

6.  结语

        略。。。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]