2026-02-27 22:59:17 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
2026-02-28 20:56:11 +08:00
|
|
|
|
#include <module/imodule.h>
|
2026-02-27 22:59:17 +08:00
|
|
|
|
#include <types/base/types.h>
|
2026-02-28 20:56:11 +08:00
|
|
|
|
#include <types/const/priority.h>
|
2026-02-27 22:59:17 +08:00
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
namespace extra2d {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 文件信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct FileInfo {
|
|
|
|
|
|
std::string path;
|
|
|
|
|
|
std::string name;
|
|
|
|
|
|
bool isDir = false;
|
|
|
|
|
|
int64 size = 0;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 文件读取结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct FileData {
|
|
|
|
|
|
bool ok = false;
|
|
|
|
|
|
std::vector<uint8> data;
|
|
|
|
|
|
std::string error;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
operator bool() const { return ok; }
|
|
|
|
|
|
const uint8* ptr() const { return data.data(); }
|
|
|
|
|
|
size_t size() const { return data.size(); }
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-02-28 20:56:11 +08:00
|
|
|
|
* @brief 文件模块
|
|
|
|
|
|
*
|
2026-02-27 22:59:17 +08:00
|
|
|
|
* 提供跨平台文件系统操作
|
2026-02-28 20:56:11 +08:00
|
|
|
|
* 非单例设计,通过 Context 管理生命周期
|
2026-02-27 22:59:17 +08:00
|
|
|
|
*/
|
2026-02-28 20:56:11 +08:00
|
|
|
|
class FileModule : public IModule {
|
2026-02-27 22:59:17 +08:00
|
|
|
|
public:
|
2026-02-28 20:56:11 +08:00
|
|
|
|
FileModule();
|
|
|
|
|
|
~FileModule() override;
|
|
|
|
|
|
|
|
|
|
|
|
// 禁止拷贝
|
|
|
|
|
|
FileModule(const FileModule&) = delete;
|
|
|
|
|
|
FileModule& operator=(const FileModule&) = delete;
|
|
|
|
|
|
|
|
|
|
|
|
// 允许移动
|
|
|
|
|
|
FileModule(FileModule&&) noexcept;
|
|
|
|
|
|
FileModule& operator=(FileModule&&) noexcept;
|
|
|
|
|
|
|
|
|
|
|
|
// IModule 接口实现
|
|
|
|
|
|
const char* name() const override { return "File"; }
|
|
|
|
|
|
ModuleType type() const override { return ModuleType::System; }
|
|
|
|
|
|
int priority() const override { return Pri::File; }
|
2026-02-27 22:59:17 +08:00
|
|
|
|
bool init() override;
|
|
|
|
|
|
void shutdown() override;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 检查文件是否存在
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool exists(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 检查是否为目录
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool isDir(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 读取整个文件到内存
|
|
|
|
|
|
*/
|
|
|
|
|
|
FileData read(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 读取文件为字符串
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string readString(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 写入数据到文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool write(const std::string& path, const void* data, size_t size) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 写入字符串到文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool writeString(const std::string& path, const std::string& content) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 追加数据到文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool append(const std::string& path, const void* data, size_t size) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 删除文件
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool remove(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 创建目录
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool mkdir(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 列出目录内容
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::vector<FileInfo> listDir(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取文件大小
|
|
|
|
|
|
*/
|
|
|
|
|
|
int64 fileSize(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取文件扩展名
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string ext(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取文件名(不含路径)
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string fileName(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取文件所在目录
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string dirName(const std::string& path) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 连接路径
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string join(const std::string& a, const std::string& b) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取可写目录(用于存档等)
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string writableDir() const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置资源根目录
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setAssetRoot(const std::string& root) { assetRoot_ = root; }
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取资源根目录
|
|
|
|
|
|
*/
|
|
|
|
|
|
const std::string& assetRoot() const { return assetRoot_; }
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取资源完整路径
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string assetPath(const std::string& relPath) const;
|
2026-02-28 20:56:11 +08:00
|
|
|
|
|
2026-02-27 22:59:17 +08:00
|
|
|
|
private:
|
|
|
|
|
|
std::string assetRoot_;
|
|
|
|
|
|
std::string writableDir_;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace extra2d
|