#ifndef __FILE_SYSTEM_H #define __FILE_SYSTEM_H // 20240226 #include "Types.h" #include "ExHeaders.h" namespace tzc { class StreamFile; class PrimeFile; class BigFile; /* continue form ErrorCode of common */ typedef enum __FILESYSTEM_ERRORCODE { E_FS_PATH_NULL = -0x3001, E_FAILED_CREATE_DIR = -0x3002, E_FAILED_OPEN_DIR = -0x3003, E_FS_ISNOT_DIR = -0x3011, E_FS_INVAILED_NAME = -0x3012, } EN_FS_ERROR; typedef enum __FILE_TYPE { FT_UNKNOWN = -1, /* 未知 */ FT_ALL = 0, /* (全部文件类型,仅限查询时使用) */ FT_REG = 1, /* 普通文件 */ FT_DIRC = 1 << 1, /* 目录 */ FT_LINK = 1 << 2, /* 软链接文件 */ FT_BLOCK = 1 << 3, /* 块设备文件 */ FT_CHAR = 1 << 4, /* 字符设备文件 */ FT_FIFO = 1 << 5, /* 管道文件 */ FT_SOCKET = 1 << 7, /* 套接字文件 */ } EN_FILE_TYPE; /* 文件信息 */ struct FileInfo { TZ_INT FileType; // tzc::EN_FILE_TYPE TZ_BOOL IsHidden; TZ_BOOL IsExist; TZ_BOOL IsRead; TZ_BOOL IsWrite; TZ_BOOL IsExec; TZ_Int64 FileSize; TZ_Int64 LastTime; /* 最后修改时间 秒级时间戳 */ std::string BaseDir; /* 文件基路径 /home/admin/xxx.suffix 的 /home/admin/ */ std::string Name; /* 文件名称 xxx.suffix */ std::string Suffix; /* 文件后缀 xxx.suffix 的 .suffix */ }; /** * @brief Path 类对文件系统的路径操作进行了封装 * * @note 1、Path类可以识别不规范的路径字符串: * 例如在Linux可以识别 \usr\local 路径字符串(规范字符串使用 '/'); * 在Windows可以识别E:/aa/bb (规范字符 '\') */ class DECLDLL Path { using PathQueue_t = std::list; public: using PathIterator = PathQueue_t::iterator; using PathConstIterator = PathQueue_t::const_iterator; static const std::string SPCH; // path separator char public: /** * @brief Path类对文件系统的操作记录将输出到单独的文件,这些内容独立于Logger日志 * * @param enable 操作记录默认关闭 需手动开启 * * @note 操作记录将输出到当前目录下 * 文件命名规则: .filesystem.${pid}.log */ static void SetOutput(TZ_BOOL enable = FALSE); public: // construction and deconstruction Path(); Path(const std::string & path); Path(const Path & path); // copy construction Path(Path && path); // move construction ~Path(); public: // override Path & operator = (const Path & path); Path & operator = (Path && path); Path & operator = (const std::string & path); Path & operator += (const Path & path); Path & operator += (Path && path); Path & operator += (const std::string & path); TZ_BOOL operator == (const Path & path); TZ_BOOL operator == (Path && path); TZ_BOOL operator == (const std::string & path); /* Path类型的隐式转换 */ operator std::string () const; public: /* 这个public部分的函数仅改变Path对象本身, 不会更改硬盘信息 */ /** * @brief 向Path对象中追加路径 * * @example * 当前有 Path对象path, 文件系统有路径"/home/admin/project/proj1/aa.txt" * 当前path对象保存了路径 "/home/admin/"; * 若想使path对象保存 "/home/admin/project/proj1" * 可调用函数 * path.PushDir("project/proj1/"); * 或 path.PushDir("project").PushDir("proj1"); */ Path & PushDir(const std::string & dir); /** * @brief 从Path对象中减少目录层级 * * @param level 无符号数 移除的目录层数 * * @return TZ_BOOL 若操作成功则返回TRUE; 否则返回FALSE * * @note 需自行保证有效性 * * @example * 当前有 Path对象path, path当前保存了 "/home/admin/project/proj1" * 若想使path返回上一级目录 * path.PopDir(); 或 path.PopDir(1); * 若想使path返回上两级目录 * path.PopDir(2); */ TZ_BOOL PopDir(TZ_Uint32 level = 1); PathConstIterator Begin() const; PathConstIterator End() const; /** * @brief 获取层级数 */ size_t Size() const; /** * @brief 清理Path对象,使Path对象不包含任何路径, 不影响任何磁盘信息 */ void Clear(); /** * @brief Path对象没有保存任何路径时返回TRUE */ TZ_BOOL IsEmpty() const; /** * @brief 获取当前 Path 类对象包含的路径 * * @return path string * * @note In Linux, the path is split by '/'. * In Windows, the path is split by '\' */ std::string ToString() const; /** * @brief 获取绝对路径 * * @note 根据当前保存路径获取绝对路径,不会改变当前对象的内容 * */ std::string ToAbsolutionPath() const; /** * @brief 获取当前路径的父目录 */ std::string GetBasePath() const; /** * @brief 获取当前路径叶节点名称 * * @example * 1、../ => .. * 2、 ./ => . * 3、/home/admin => admin */ std::string GetLeafName() const; /** * @brief 将Path对象内的相对路径转换为绝对路径 */ void ConvertAbsolutionPath(); /** * @brief 判断当前Path对象是否是传入参数的祖先路径 * * @note !!不建议使用相对路径进行路径关系判断 * * @example * 存在路径 /home/admin/project/common/include/Logger.h * 存在路径 /home/admin/project/common/source/Logger.cpp * 存在路径 /home/admin/test * 当前Path对象已保存路径:/home/admin/project/, 则: * * 1、this->IsParentPath("/home/admin/project/") * 或 this->IsParentPath(Path("/home/admin/project/")) * * 返回FALSE:若两个路径相等, 不认为具有祖先关系 * * 2、this->IsParentPath("/home/admin/project/common/source/Logger.cpp") * 或 this->IsParentPath(Path("/home/admin/project/common/source/Logger.cpp")) * * 返回TRUE: 当前对象(/home/admin/project/) 是传入对象或路径的祖先 * * 3、this->IsParentPath("/home/admin/test") * 或 this->IsParentPath(Path("/home/admin/test")) * * 返回FALSE:当前对象(/home/admin/project/) 与传入对象或路径(/home/admin/test)不具有祖先关系 * */ TZ_BOOL IsParentPath(const Path & path); TZ_BOOL IsParentPath(const std::string & path); /** * @brief 判断当前Path对象是否是传入参数的后代路径 * * @note !!不建议使用相对路径进行路径关系判断 * * @example * 存在路径 /home/admin/project/common/include/Logger.h * 存在路径 /home/admin/project/common/source/Logger.cpp * 存在路径 /home/admin/test * 当前Path对象已保存路径:/home/admin/project/common/include/, 则: * * 1、this->IsSubPath("/home/admin/project/common/include/") * 或 this->IsSubPath(Path("/home/admin/project/common/include/")) * * 返回FALSE:若两个路径相等, 不认为具有后代关系 * * 2、this->IsSubPath("/home/admin/project/") * 或 this->IsSubPath(Path("/home/admin/project/")) * * 返回TRUE:当前对象(/home/admin/project/common/include/) 是 * 传入对象或路径(/home/admin/project/)的后代路径 * * 3、this->IsSubPath("/home/admin/project/common/source/Logger.cpp") * 或 this->IsSubPath(Path("/home/admin/project/common/source/Logger.cpp")) * * 返回FALSE: 当前对象(/home/admin/project/common/include/) 不是传入对象或路径的后代路径 * * 4、注意!! * 若存在绝对路径/home/admin/project/common/include/ * 程序在路径/home/admin/project/common/include运行, 初始化Path对象路径为./ * * 判断路径关系 Path("./").IsSubPath("/home/admin/project/"); 将会返回FALSE * * 分析: * 路径关系判断基于初始化路径字符串的, "." 不等于 "home" , 因此返回FALSE * * 但是Path对象指向的 "./" 的实际路径(/home/admin/project/common/include)确实为 * 路径(/home/admin/project/) 的后代路径, 若想得到与实际情况一致的结果,需将对象 * 转换为绝对路径后进行比较。 */ TZ_BOOL IsSubPath(const Path & path); TZ_BOOL IsSubPath(const std::string & path); /** * @brief 检查路径各级名称是否合法 * * @note Linux: 文件或目录名称不能超过255个字符 !不推荐使用特殊字符('<' '>' '?' '*') * Windows: 长度不超过256字节 不能使用 / \ : * ? " < > | */ TZ_BOOL CheckName(); /** @brief 返回 当前保存路径和 dir的拼接字符串 */ const std::string Joint(const std::string & dir) const; public: /** * @brief 拼接路径 */ static const std::string Joint(const std::string & path, const std::string & dir); protected: /** * @brief 重新分配构造对象 */ void assign(const std::string & path); /** * @brief 解析路径字符串 */ void serialize(const std::string & path); void serialize(const std::list & list); /** * @brief 对路径中存在的相对路径进行优化 * * @example "./aa/bb/cc/../../../" => "./" */ void format(); /** * @brief 不带格式的 */ std::string tostring() const; TZ_BOOL isAllBaseDir() const; protected: /** * @note m_pathList 的第一项若为 "." 或 ".." 则代表这是相对路径,否则为绝对路径 */ std::list m_pathList; }; // Path override operator + Path operator + (const Path & path, const Path & pathr); Path operator + (const Path & path, const std::string & str); Path operator + (const std::string & str, const Path & path); /** * @brief ExecPath 完全继承Path, 在Path的基础上实现了对文件系统的操作 * * Path 处理路径 * ExecPath 实现文件系统操作 */ class DECLDLL ExecPath : public Path { public: ExecPath(); ExecPath(const std::string & path); ExecPath(const Path & path); // copy construction ExecPath(Path && path); // move construction ExecPath(const ExecPath & path); // copy construction ExecPath(ExecPath && path); // move construction public: /** 对文件系统的若干操作 */ /** * @brief * 以下若干函数用于获取路径指向的目录或文件的属性,包括 存在性,读写执行权限, * 隐藏性,文件类型;或这些信息的集合 * * @param path 一个合法的路径字符串,可以是文件,可以是目录 * * @return TZ_BOOL */ /** @brief 判断当前对象包含的路径是否存在 */ TZ_BOOL IsExist() const; TZ_BOOL IsExec() const; TZ_BOOL IsRead() const; TZ_BOOL IsWrite() const; TZ_BOOL IsHidden() const; /** * @brief 获取文件信息 */ FileInfo GetFileInfo() const; /** * @brief 文件类型判断 * @return enum tzc::EN_FILE_TYPE */ TZ_INT GetFileType() const; /** @brief 判断当前对象包含的路径是否是目录 */ TZ_BOOL IsDirectory() const; /** @brief 判断当前对象包含的路径是否是普通文件 */ TZ_BOOL IsRegFile() const; /** @brief 判断当前对象包含的路径是否是软连接文件 */ TZ_BOOL IsLinkFile() const; /** @brief 判断当前对象包含的路径是否是隐藏文件 */ TZ_BOOL IsHiddenFile() const; /** @brief 判断当前对象包含的路径是否是块设备文件 */ TZ_BOOL IsBlockDevFile() const; /** @brief 判断当前对象包含的路径是否是字符设备文件 */ TZ_BOOL IsCharDevFile() const; /** @brief 判断当前对象包含的路径是否是FIFO文件 */ TZ_BOOL IsFifoFile() const; /** @brief 判断当前对象包含的路径是否是套接字文件 */ TZ_BOOL IsSocketFile() const; /** @brief 获取文件实际大小 */ TZ_Int64 GetFileSize() const; /** @brief 获取文件占用空间大小 */ TZ_Int64 GetFileUsage() const; /** * @brief 获取文件最后一次访问时间 * @return 秒级时间戳 */ TZ_Int64 LastVisitTime() const; /** * @brief 获取文件最后一次内容被修改时间 * @return 秒级时间戳 */ TZ_Int64 LastContentModifyTime() const; /** * @brief 获取文件最后一次文件属性被修改时间 * @return 秒级时间戳 */ TZ_Int64 LastStatusModifyTime() const; /** * @brief * 以下若干函数用于查询路径指向的目录内包含的文件或目录列表 * 可选择仅获取列表或详细信息 * * @param type 来自 enum tzc::EN_FILE_TYPE * @param pre std::string 前缀 * @param suffix std::string 后缀 * * @note 若路径指向的不是一个目录, 则报错 */ TZ_INT GetFileList(std::list & list, TZ_Uint32 type = 0) const; TZ_INT GetFileList(std::list & list, TZ_Uint32 type = 0) const; TZ_INT GetFileListByPre(std::list & list, const std::string & pre, TZ_Uint32 type = 0) const; TZ_INT GetFileListByPre(std::list & list, const std::string & pre, TZ_Uint32 type = 0) const; TZ_INT GetFileListBySuffix(std::list & list, const std::string & suffix, TZ_Uint32 type = 0) const; TZ_INT GetFileListBySuffix(std::list & list, const std::string & suffix, TZ_Uint32 type = 0) const; /** * @brief 创建路径指向的目录 * * @note 若路径不存在则创建 */ TZ_INT CreateDir(); /** * @brief 确保目录存在 * * @note 此函数判断路径是否存在 * 若存在,则返回TRUE; * 若不存在,则创建指向的目录,并返回TRUE; * 若不存在且创建失败,则返回FALSE */ TZ_BOOL AssureExist(); /** * @brief 在当前路径下创建子目录 * * @return 成功返回0; 失败返回非0值 */ TZ_INT CreateSubDir(const Path & path); TZ_INT CreateSubDir(const std::string & path); /** * @brief 移除当前包含的目录 * * @param isForce TZ_BOOL 若为真,则立即移除包含目录(相当于 rm -rf) * * @note 此函数仅能删除空目录,如果需要删除非空目录,需指定isForce为真 */ TZ_INT Remove(TZ_BOOL isForce = FALSE); /** * @brief 对当前路径的叶节点进行重命名 * * @param name std::string 文件或目录的新名称 名称需符合当前系统命名规则 * 重命名操作仅在当前目录进行, name中不能出现 字符\ 或 字符/ * * @note !此函数不能进行文件或目录的移动 移动需使用 Move函数 * !操作成功将会改变Path对象内存储的路径 * * @return 成功返回0,失败返回非0值 */ TZ_INT Rename(const std::string & name); /** * @brief 将当前路径指向的文件或目录 移动 到新路径 * !操作成功将会改变Path对象内存储的路径 * * @param path std::string path必须是一个 已存在的 目录 路径 * * @note 1、若当前保存的路径指向一个文件,则将此文件移动到path内 * 2、若当前保存的路径指向一个目录,则将此目录整体移动到path内 */ TZ_INT Move(const std::string & path); /** * @brief 清空当前路径(如果是一个目录)下的所有文件 * * @param type 来自 enum tzc::EN_FILE_TYPE */ TZ_INT ClearDir(TZ_Uint32 type = 0); /** * @brief 获取文件夹下所有文件的总大小,会递归计算文件夹下的文件夹 * @return 成功返回文件总大小, 失败返回-1 * * @note 若当前指向一个不存在的路径,返回-1 * 若当前指向一个文件 返回这个文件的大小 * 若当前指向一个文件夹 返回这个文件夹的总大小 * * 这个函数计算的是文件内容的大小,不是占用空间的大小 */ TZ_Int64 GetDirectoryContentSize() const; public: /** common link */ SPtr GetStreamFilePtr() const; SPtr GetPrimeFilePtr() const; SPtr GetBigFilePtr() const; Path GetPathObject(); }; namespace filesystem { /** * @brief 获取当前工作路径 */ DECLDLL std::string GetCurWorkDir(); /** * @brief 检测 path 是否存在 * * @param path 一个合法的路径字符串,可以是文件,可以是目录 * * @return TZ_BOOL */ DECLDLL TZ_BOOL IsExist(const std::string & path); /** * @brief 检测 path 是否具有可执行权限 * * @param path 一个合法的路径字符串,可以是文件,可以是目录 * * @return TZ_BOOL */ DECLDLL TZ_BOOL IsExec(const std::string & path); /** * @brief 检测 path 是否具有读取权限 * * @param path 一个合法的路径字符串,可以是文件,可以是目录 * * @return TZ_BOOL */ DECLDLL TZ_BOOL IsRead(const std::string & path); /** * @brief 检测 path 是否可写 * * @param path 一个合法的路径字符串,可以是文件,可以是目录 * * @return TZ_BOOL */ DECLDLL TZ_BOOL IsWrite(const std::string & path); /** * @brief 判断path是否是隐藏文件 */ DECLDLL TZ_BOOL IsHidden(const std::string & path); /** * @brief 获取文件类型 * * @return enum tzc::EN_FILE_TYPE * */ DECLDLL TZ_INT GetFileType(const std::string & path); /** * @brief 获取文件信息 */ FileInfo GetFileInfo(const std::string & path); /** * @brief 仅创建当前 * */ DECLDLL TZ_INT CreateDir(const std::string & path); DECLDLL TZ_INT Remove(const std::string & path, TZ_BOOL isForce = FALSE); /** * @brief 对路径的叶节点进行重命名 * * @param name std::string 文件或目录的新名称 名称需符合当前系统命名规则 * 重命名操作仅在当前目录进行, name中不能出现 字符\ 或 字符/ * * @note !此函数不能进行文件或目录的移动 移动需使用 Move函数 * * @return 成功返回0,失败返回非0值 */ DECLDLL TZ_INT Rename(const std::string & path, const std::string & name); /** * @brief 将路径指向的文件或目录 移动或重命名 到新路径 */ DECLDLL TZ_INT Move(const std::string & path, const std::string & newpath); /** * @brief 清空当前路径(如果是一个目录)下的所有文件 * * @param type 来自 enum tzc::EN_FILE_TYPE */ DECLDLL TZ_INT ClearDir(const std::string & path, TZ_Uint32 type = 0); /** * @brief 获取指定目录下的文件列表 * * @param type 来自 enum tzc::EN_FILE_TYPE */ DECLDLL TZ_INT GetFileList(const std::string & path, std::list & list, TZ_Uint32 type = 0); /** * @brief 获取指定目录下的文件列表和文件详细信息 * * @param type 来自 enum tzc::EN_FILE_TYPE */ DECLDLL TZ_INT GetFileList(const std::string & path, std::list & list, TZ_Uint32 type = 0); /** * @brief 根据前缀获取指定目录下文件列表 * * @param type 来自 enum tzc::EN_FILE_TYPE */ DECLDLL TZ_INT GetFileListByPre(const std::string & path, std::list & list, const std::string & pre, TZ_Uint32 type = 0); /** * @brief 根据前缀获取指定目录下文件列表和文件详细信息 * * @param type 来自 enum tzc::EN_FILE_TYPE */ DECLDLL TZ_INT GetFileListByPre(const std::string & path, std::list & list, const std::string & pre, TZ_Uint32 type = 0); /** * @brief 根据后缀获取指定目录下文件列表 * * @param type 来自 enum tzc::EN_FILE_TYPE */ DECLDLL TZ_INT GetFileListBySuffix(const std::string & path, std::list & list, const std::string & suffix, TZ_Uint32 type = 0); /** * @brief 根据后缀获取指定目录下文件列表和文件详细信息 * * @param type 来自 enum tzc::EN_FILE_TYPE */ DECLDLL TZ_INT GetFileListBySuffix(const std::string & path, std::list & list, const std::string & suffix, TZ_Uint32 type = 0); /** * @brief 检查路径各级名称是否合法 */ DECLDLL TZ_BOOL CheckName(const std::string & path); } // namespace filesystem }; // namespace tzc { #endif // !__FILE_SYSTEM_H