#pragma once #include #include #include #include #include namespace frostbite2D { namespace fs = std::filesystem; /** * @brief 文件信息结构体 */ struct FileInfo { std::string name; ///< 文件名(包含扩展名) std::string extension; ///< 文件扩展名(包含点,如 ".txt") std::string fullPath; ///< 完整路径 uint64 size = 0; ///< 文件大小(字节) bool isDirectory = false; ///< 是否为目录 bool isRegularFile = false; ///< 是否为普通文件 bool exists = false; ///< 是否存在 }; /** * @brief 资源管理类(单例) * * 提供文件读写、目录操作、路径处理等功能。 * 支持设置工作目录,所有相对路径将基于工作目录解析。 * 支持 UTF-8 编码的中文路径。 * * @example * auto& asset = Asset::get(); * asset.setWorkingDirectory("D:/游戏/资源"); * std::string content; * asset.readTextFile("配置/设置.json", content); */ class Asset { public: /** * @brief 获取单例实例 * @return 资源管理器实例引用 */ static Asset &get(); Asset(const Asset &) = delete; Asset &operator=(const Asset &) = delete; // --------------------------------------------------------------------------- // 文件读写 // --------------------------------------------------------------------------- /** * @brief 读取文本文件 * @param path 文件路径(相对或绝对路径) * @param outContent 输出文件内容 * @return 读取成功返回 true */ bool readTextFile(const std::string &path, std::string &outContent); /** * @brief 写入文本文件 * @param path 文件路径 * @param content 要写入的内容 * @param append 是否追加模式,默认覆盖 * @return 写入成功返回 true */ bool writeTextFile(const std::string &path, const std::string &content, bool append = false); /** * @brief 读取二进制文件 * @param path 文件路径 * @param outData 输出字节数组 * @return 读取成功返回 true */ bool readBinaryFile(const std::string &path, std::vector &outData); /** * @brief 写入二进制文件 * @param path 文件路径 * @param data 要写入的字节数组 * @param append 是否追加模式,默认覆盖 * @return 写入成功返回 true */ bool writeBinaryFile(const std::string &path, const std::vector &data, bool append = false); /** * @brief 读取文本文件到字符串(便捷方法) * @param path 文件路径 * @return 文件内容,失败返回 std::nullopt */ std::optional readFileToString(const std::string &path); /** * @brief 读取二进制文件到字节数组(便捷方法) * @param path 文件路径 * @return 字节数组,失败返回 std::nullopt */ std::optional> readFileToBytes(const std::string &path); // --------------------------------------------------------------------------- // 文件/目录检查 // --------------------------------------------------------------------------- /** * @brief 检查路径是否存在 * @param path 路径 * @return 存在返回 true */ bool exists(const std::string &path) const; /** * @brief 检查路径是否为目录 * @param path 路径 * @return 是目录返回 true */ bool isDirectory(const std::string &path) const; /** * @brief 检查路径是否为普通文件 * @param path 路径 * @return 是普通文件返回 true */ bool isRegularFile(const std::string &path) const; /** * @brief 检查文件或目录是否为空 * @param path 路径 * @return 为空返回 true */ bool isEmpty(const std::string &path) const; // --------------------------------------------------------------------------- // 目录操作 // --------------------------------------------------------------------------- /** * @brief 创建单层目录 * @param path 目录路径 * @return 创建成功返回 true */ bool createDirectory(const std::string &path); /** * @brief 递归创建多层目录 * @param path 目录路径 * @return 创建成功返回 true */ bool createDirectories(const std::string &path); /** * @brief 删除文件 * @param path 文件路径 * @return 删除成功返回 true */ bool removeFile(const std::string &path); /** * @brief 删除目录及其所有内容 * @param path 目录路径 * @return 删除成功返回 true */ bool removeDirectory(const std::string &path); // --------------------------------------------------------------------------- // 文件操作 // --------------------------------------------------------------------------- /** * @brief 复制文件 * @param from 源文件路径 * @param to 目标文件路径 * @param overwrite 是否覆盖已存在的文件 * @return 复制成功返回 true */ bool copyFile(const std::string &from, const std::string &to, bool overwrite = false); /** * @brief 移动文件 * @param from 源文件路径 * @param to 目标文件路径 * @return 移动成功返回 true */ bool moveFile(const std::string &from, const std::string &to); /** * @brief 重命名文件或目录 * @param oldPath 原路径 * @param newPath 新路径 * @return 重命名成功返回 true */ bool rename(const std::string &oldPath, const std::string &newPath); // --------------------------------------------------------------------------- // 目录遍历 // --------------------------------------------------------------------------- /** * @brief 列出目录中的所有文件 * @param directoryPath 目录路径 * @param recursive 是否递归遍历子目录 * @return 文件路径列表 */ std::vector listFiles(const std::string &directoryPath, bool recursive = false); /** * @brief 列出目录中的所有子目录 * @param directoryPath 目录路径 * @param recursive 是否递归遍历子目录 * @return 子目录路径列表 */ std::vector listDirectories(const std::string &directoryPath, bool recursive = false); /** * @brief 列出目录中的所有文件和子目录 * @param directoryPath 目录路径 * @param recursive 是否递归遍历子目录 * @return 所有项目路径列表 */ std::vector listAll(const std::string &directoryPath, bool recursive = false); /** * @brief 按扩展名列出文件 * @param directoryPath 目录路径 * @param extension 文件扩展名(如 ".png") * @param recursive 是否递归遍历子目录 * @return 匹配的文件路径列表 */ std::vector listFilesWithExtension(const std::string &directoryPath, const std::string &extension, bool recursive = false); // --------------------------------------------------------------------------- // 文件信息 // --------------------------------------------------------------------------- /** * @brief 获取文件详细信息 * @param path 文件路径 * @return 文件信息结构体 */ FileInfo getFileInfo(const std::string &path); /** * @brief 获取文件大小 * @param path 文件路径 * @return 文件大小(字节) */ uint64 getFileSize(const std::string &path) const; // --------------------------------------------------------------------------- // 路径处理 // --------------------------------------------------------------------------- /** * @brief 获取文件名(包含扩展名) * @param path 文件路径 * @return 文件名 */ std::string getFileName(const std::string &path) const; /** * @brief 获取文件名(不含扩展名) * @param path 文件路径 * @return 文件名 */ std::string getFileNameWithoutExtension(const std::string &path) const; /** * @brief 获取文件扩展名 * @param path 文件路径 * @return 扩展名(包含点,如 ".txt") */ std::string getExtension(const std::string &path) const; /** * @brief 获取父目录路径 * @param path 文件路径 * @return 父目录路径 */ std::string getParentPath(const std::string &path) const; /** * @brief 获取绝对路径 * @param path 相对或绝对路径 * @return 绝对路径 */ std::string getAbsolutePath(const std::string &path) const; /** * @brief 获取规范路径(解析符号链接和相对路径) * @param path 路径 * @return 规范化路径 */ std::string getCanonicalPath(const std::string &path) const; /** * @brief 合并两个路径 * @param left 左侧路径 * @param right 右侧路径 * @return 合并后的路径 */ std::string combinePath(const std::string &left, const std::string &right) const; /** * @brief 规范化路径(转换为系统首选格式) * @param path 路径 * @return 规范化路径 */ std::string normalizePath(const std::string &path) const; // --------------------------------------------------------------------------- // 工作目录 // --------------------------------------------------------------------------- /** * @brief 获取当前工作目录 * @return 当前工作目录路径 */ std::string getCurrentPath() const; /** * @brief 设置当前工作目录 * @param path 目录路径 * @return 设置成功返回 true */ bool setCurrentPath(const std::string &path); /** * @brief 设置资源工作目录 * * 设置后,所有相对路径操作都将基于此目录。 * * @param path 工作目录路径 */ void setWorkingDirectory(const std::string &path); /** * @brief 获取资源工作目录 * @return 工作目录路径 */ const std::string &getWorkingDirectory() const; /** * @brief 解析相对路径为完整路径 * @param relativePath 相对路径 * @return 完整路径 */ std::string resolvePath(const std::string &relativePath) const; // --------------------------------------------------------------------------- // 资源根目录 // --------------------------------------------------------------------------- /** * @brief 设置资源根目录 * @param root 资源根目录路径 */ void setAssetRoot(const std::string &root); /** * @brief 获取资源根目录 * @return 资源根目录路径 */ const std::string &getAssetRoot() const; /** * @brief 解析资源相对路径 * * 将相对路径解析为:工作目录/资源根目录/相对路径 * * @param relativePath 相对路径 * @return 完整路径 */ std::string resolveAssetPath(const std::string &relativePath) const; private: Asset() = default; ~Asset() = default; fs::path toPath(const std::string &path) const; std::string fromPath(const fs::path &path) const; std::string resolveFullPath(const std::string &path) const; std::string workingDirectory_; std::string assetRoot_; }; } // namespace frostbite2D