Frostbite2D/Fostbite2D/include/fostbite2D/utils/asset.h

398 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <filesystem>
#include <fostbite2D/types/type_alias.h>
#include <optional>
#include <string>
#include <vector>
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<uint8> &outData);
/**
* @brief 写入二进制文件
* @param path 文件路径
* @param data 要写入的字节数组
* @param append 是否追加模式,默认覆盖
* @return 写入成功返回 true
*/
bool writeBinaryFile(const std::string &path, const std::vector<uint8> &data,
bool append = false);
/**
* @brief 读取文本文件到字符串(便捷方法)
* @param path 文件路径
* @return 文件内容,失败返回 std::nullopt
*/
std::optional<std::string> readFileToString(const std::string &path);
/**
* @brief 读取二进制文件到字节数组(便捷方法)
* @param path 文件路径
* @return 字节数组,失败返回 std::nullopt
*/
std::optional<std::vector<uint8>> 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<std::string> listFiles(const std::string &directoryPath,
bool recursive = false);
/**
* @brief 列出目录中的所有子目录
* @param directoryPath 目录路径
* @param recursive 是否递归遍历子目录
* @return 子目录路径列表
*/
std::vector<std::string> listDirectories(const std::string &directoryPath,
bool recursive = false);
/**
* @brief 列出目录中的所有文件和子目录
* @param directoryPath 目录路径
* @param recursive 是否递归遍历子目录
* @return 所有项目路径列表
*/
std::vector<std::string> listAll(const std::string &directoryPath,
bool recursive = false);
/**
* @brief 按扩展名列出文件
* @param directoryPath 目录路径
* @param extension 文件扩展名(如 ".png"
* @param recursive 是否递归遍历子目录
* @return 匹配的文件路径列表
*/
std::vector<std::string>
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