带QT界面的文件管理系统

884次阅读
没有评论

共计6127个字符,预计需要花费16分钟才能阅读完成。

下载地址

开源地址:https://github.com/mcdudu233/FileSystem.git
下载地址:https://github.com/mcdudu233/FileSystem/releases/tag/exe

代码设计

1. 先设计好 FCB 的结构和目录项的结构

class file {
private:
    /* 基本信息 */
    string name;      // * 关键字:文件名
    string father;    // 所属的目录名
    vector<int> point;// 所有数据块的指针
    /* 存取控制 */
    int master;          // 所属用户
    char masterPrivilege;// 主用户权限
    char otherPrivilege; // 其他用户权限
    /* 使用信息 */
    int size;                                   // 大小
    chrono::system_clock::time_point createTime;// 创建时间
    chrono::system_clock::time_point modifyTime;// 修改时间 

我们根据 cpp 类的特性,将 FCB 简化成一个 file 类,其中包含 FCB 的基本信息、存取控制信息和使用信息,以文件名为关键字。同时,我们采取的是单级索引组织方式,因此设定了所有数据块的指针数组。

对于目录也是一个道理,我们将目录项分为子目录和文件分开保存,关键字为目录名:

class directory {
private:
    /* 基本信息 */
    string name;                  // * 关键字:目录名
    string father;                // 父目录的目录名
    vector<directory> directories;// 目录下的子目录
    vector<file> files;           // 目录下的文件
    /* 存取控制 */
    int master = user_root.getUid();// 所属用户
    char masterPrivilege;           // 所有者权限
    char otherPrivilege;            // 其他人权限
    /* 使用信息 */
    chrono::system_clock::time_point createTime;// 创建时间
    chrono::system_clock::time_point modifyTime;// 修改时间 

对于用户,我们同样设立一个类进行管理:

class user {
private:
    int uid;        // * 关键字:用户 uid
    string name;    // 用户名
    string password;// 用户密码 采用 MD5 加密
    bool superuser; // 是否是超级用户 

2. 完善每一个类的方法和属性

file(文件)类:

public:
    file();
    file(const string &fileName, string father, int master);
    file(const file &file);
    ~file();
    bool operator==(const file &other);

public:
    string getName();         // 获取用户名
    bool setName(string name);// 设置用户名
    int getSize();            // 获取文件大小

    /* 文件操作 */
    bool clearFile();                    // 清空所有文件内容
    char *readFile();                    // 读取的文件内容
    bool writeFile(char *data, int size);// 写入文件内容

    /* 存取控制 */
    int getUser();                                        // 获取用户
    bool setUser(int uid);                                // 设置用户
    bool setMasterPrivilege(char masterPrivilege);        // 设置文件所有者权限
    bool setOtherPrivilege(char otherPrivilege);          // 设置其他用户的权限
    bool hasMasterPrivilege_read(char masterPrivilege);   // 判断所有者是否有读取权限
    bool hasMasterPrivilege_write(char masterPrivilege);  // 判断所有者是否有写入权限
    bool hasMasterPrivilege_execute(char masterPrivilege);// 判断所有者是否有执行权限
    bool hasOtherPrivilege_read(char otherPrivilege);     // 判断其他用户是否有读取权限
    bool hasOtherPrivilege_write(char otherPrivilege);    // 判断其他用户是否有写入权限
    bool hasOtherPrivilege_execute(char otherPrivilege);  // 判断其他用户是否有执行权限

    /* 使用信息 */
    chrono::system_clock::time_point getCreateTime();// 获取创建时间
    chrono::system_clock::time_point getModifyTime();// 获取修改时间

    /* 序列化 */
    void serialize(fstream &out) const;// 序列化
    void deserialize(fstream &in);     // 反序列化 

directory(文件夹)类:

public:
    directory();
    directory(string name, string father, int master);
    directory(const directory &dir);
    ~directory();
    bool operator==(const directory &other);

public:
    string getName();             // 获取目录名
    bool setName(string name);    // 设置用户名
    string getFather();           // 获取父目录名
    bool setFather(string father);// 设置父目录名

    /* 目录操作 */
    vector<directory> *getDirectories(); // 获取所有子目录
    vector<file> *getFiles();            // 获取所有文件
    bool addFile(file file);             // 新增文件
    bool addDirectory(directory dir);    // 新增目录
    bool removeFile(string name);        // 删除文件
    bool removeDirectory(string name);   // 删除目录
    file *getFile(string name);          // 根据名字获取文件 没有返回 nullptr
    directory *getDirectory(string name);// 根据名字获取目录 没有返回 nullptr
    bool has(string name);               // 目录中有这个文件 (目录或者文件)
    bool hasFile(string name);           // 目录中有这个文件
    bool hasDirectory(string name);      // 目录中有这个目录

    /* 存取控制 */
    int getUser();                                        // 获取所属用户
    bool setUser(int uid);                                // 设置所属用户
    char getMasterPrivilege();                            // 获取所有者权限
    char getOtherPrivilege();                             // 获取其他用户权限
    bool hasMasterPrivilege_read(char masterPrivilege);   // 判断所有者是否有读取权限
    bool hasMasterPrivilege_write(char masterPrivilege);  // 判断所有者是否有写入权限
    bool hasMasterPrivilege_execute(char masterPrivilege);// 判断所有者是否有执行权限
    bool hasOtherPrivilege_read(char otherPrivilege);     // 判断其他用户是否有读取权限
    bool hasOtherPrivilege_write(char otherPrivilege);    // 判断其他用户是否有写入权限
    bool hasOtherPrivilege_execute(char masterPrivilege); // 判断其他用户是否有执行权限

    /* 使用信息 */
    chrono::system_clock::time_point getCreateTime();// 获取创建时间
    chrono::system_clock::time_point getModifyTime();// 获取修改时间

    /* 序列化 */
    void serialize(fstream &out) const;// 序列化
    void deserialize(fstream &in);     // 反序列化
};

// 根目录
extern directory dir_root;

user(用户)类:

public:
    user();
    user(int uid, string name, string password = "", bool superuser = false);
    ~user();
    bool operator==(const user &other);

public:
    int getUid();                       // 获取 UID
    string getName();                   // 获取用户名
    bool setName(string name);          // 设置用户名
    string getPassword();               // 获取用户密码 MD5
    bool setPassword(string password);  // 设置用户密码
    bool checkPassword(string password);// 检测密码是否一致
    bool getSuper();                    // 判断是否为超级用户
    bool setSuper(bool super);          // 设置是否为超级用户

    /* 序列化 */
    void serialize(fstream &out) const;// 序列化
    void deserialize(fstream &in);     // 反序列化
};

// 默认用户
extern user user_root;

3. 数据处理的方法

我们采用单文件来保存数据,即用后缀“.hwh.xb.fs”的文件来保存我们自制的文件系统:

namespace fs = std::filesystem;

// 文件系统数据的存放路径
#define DATA_PATH "./"
#define DATA_SUFFIX ".hwh.xb.fs"

bool initData(const string &name);
bool closeData();
bool existData(const string &name);
bool setAvailable(vector<bool> *v, int start);
int getSpaceSize();
bool setSpaceSize(int size);
int getBlockSize();
bool setBlockSize(int size);
bool setPosition(int block);// 设置读写指针位置
fstream &getData();         // 获取 file

/* 文件数据读写方法 */
bool hasBlock(int block);                        // 判断块是否已经有数据了
int availableBlock();                            // 获取空闲块
bool useBlock(int block);                        // 使用空闲块
bool releaseBlock(int block);                    // 释放已经使用的块
char *readBlock(int block);                      // 读取某一块
bool writeBlock(int block, char *data, int size);// 写入某一块

#endif//FILESYSTEM_DATA_H

接着测试读写的方法,初始化文件内容为 16 进制的全 0,这里我们采用 winhex 软件来测试查看:

带 QT 界面的文件管理系统

测试无误,数据初始化为全 0。

4. 完成文件系统(filesystem)类

该类用于调用并实现文件系统操作,要用到前面所有的类。
首先包含一个文件系统应有的私有属性:

private:
    vector<string> current;// 当前所在的路径
    string name;           // 文件系统数据的文件名
    int space_size;        // 空间大小
    int block_size;        // 块大小
    int block_data;        // 开始存数据部分的块地址

    user *user_current;// 当前操作系统的用户
    vector<user> users;// 所有用户
    directory tree;    // 根目录

    vector<bool> available;// 空闲盘块 位视图法 

在这里我们采用位示图法保存空闲盘块的数据,因为这种方法简单且有效,修改效率高。
接着我们完成文件系统可能用到的所有操作:

public:
    /* 基本 */
    string getCurrentPath();                  // 获取当前所在的路径
    directory *getTree();                     // 获取树形目录
    directory *getFatherByName(directory dir);// 根据目录找到父目录
    directory *getFatherByName(file f);       // 根据文件找到父目录
    directory *findParentDirectory(directory *current, directory &target);
    directory *findParentDirectory(directory *current, file &target);
    /* 命令 */
    bool ls(vector<List> &v);                                                    // 列出当前文件夹下的文件
    bool ls(string path, vector<List> &v);                                       // 列出某个文件夹下的文件
    int disk(bool left);                                                         // 获取磁盘容量 (left 为 true 时返回剩余容量)
    bool cd(string path);                                                        // 跳转到某个文件夹
    bool mkdir(directory d, const string &dname);                                // 新建文件夹
    bool touch(directory d, const string &fname);                                // 新建文件
    bool rm(file f);                                                             // 删除文件
    bool rm(directory d);                                                        // 删除目录
    vector<user> usrs();                                                         // 获取所有用户
    int useradd(string name, string password = "", bool super = false);          // 新增用户
    bool userdel(int uid);                                                       // 删除用户
    bool usercrg(int uid, string name, string password = "", bool super = false);// 修改用户信息
    user userbyid(int uid);                                                      // 根据 uid 查找用户 

再接下来就是测试我们的文件系统类了,我们尝试初始化该类并写入了一些文件和文件夹信息:

带 QT 界面的文件管理系统

很明显文件结构被写入到该文件的首部(我们的文件系统默认分配一定的首部空间写入文件结构信息)

界面设计

界面

(1)格式化窗口设计

带 QT 界面的文件管理系统

(2)登录界面设计

带 QT 界面的文件管理系统

(3)主界面设计

带 QT 界面的文件管理系统

(4)右键菜单

带 QT 界面的文件管理系统

(5)文本编辑界面

带 QT 界面的文件管理系统

(6)顶部功能菜单

带 QT 界面的文件管理系统

界面代码

界面代码请查看源代码,这里不占用宝贵的空间进行赘述了。

结果

带 QT 界面的文件管理系统

分析后共 3689 行代码。

正文完
 0
评论(没有评论)
验证码
zh_CN简体中文