mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 21:34:28 +08:00
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件 - 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明 - 提供完整的 API 使用示例路径、最佳实践与性能建议 - 包含架构图、依赖关系图与故障排查指南 - 添加测试用例参考与扩展方法说明 - [skip ci]
17 KiB
17 KiB
存储系统 API
**本文引用的文件列表** - [IStorage.cs](file://GFramework.Core.Abstractions/storage/IStorage.cs) - [IFileStorage.cs](file://GFramework.Game.Abstractions/storage/IFileStorage.cs) - [IScopedStorage.cs](file://GFramework.Game.Abstractions/storage/IScopedStorage.cs) - [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs) - [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs) - [ISerializer.cs](file://GFramework.Game.Abstractions/serializer/ISerializer.cs) - [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs) - [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs) - [ReadMe.md](file://GFramework.Game/storage/ReadMe.md)目录
简介
本文件为 GFramework.Storage 系统的完整 API 参考文档,覆盖以下主题:
- 基础存储接口 IStorage 的设计理念与扩展机制
- 文件存储接口 IFileStorage 的方法与使用要点
- 作用域存储接口 IScopedStorage 的命名空间隔离与批量操作能力
- FileStorage 的具体实现细节(文件路径管理、权限控制、错误处理)
- ScopedStorage 的作用域概念与典型使用场景(临时数据、会话数据)
- 序列化器接口 ISerializer 的配合使用,提供数据持久化完整方案
- 常见存储需求的实践示例(配置文件、用户数据、游戏进度)
项目结构
GFramework.Storage 系统由“抽象接口层 + 平台实现层 + 工具层”组成:
- 抽象接口层:定义跨平台统一的存储契约(IStorage、IFileStorage、IScopedStorage)
- 平台实现层:提供具体实现(FileStorage、GodotFileStorage、ScopedStorage)
- 工具层:序列化器(ISerializer、JsonSerializer)
graph TB
subgraph "抽象接口层"
IStorage["IStorage 接口"]
IFileStorage["IFileStorage 接口"]
IScopedStorage["IScopedStorage 接口"]
ISerializer["ISerializer 接口"]
end
subgraph "平台实现层"
FileStorage["FileStorage 实现"]
GodotFileStorage["GodotFileStorage 实现"]
ScopedStorage["ScopedStorage 实现"]
end
subgraph "工具层"
JsonSerializer["JsonSerializer 实现"]
end
IFileStorage --> IStorage
IScopedStorage --> IStorage
FileStorage --> IFileStorage
GodotFileStorage --> IStorage
ScopedStorage --> IScopedStorage
FileStorage --> ISerializer
GodotFileStorage --> ISerializer
JsonSerializer --> ISerializer
图表来源
- IStorage.cs
- IFileStorage.cs
- IScopedStorage.cs
- FileStorage.cs
- GodotFileStorage.cs
- ScopedStorage.cs
- ISerializer.cs
- JsonSerializer.cs
章节来源
- IStorage.cs
- IFileStorage.cs
- IScopedStorage.cs
- FileStorage.cs
- GodotFileStorage.cs
- ScopedStorage.cs
- ISerializer.cs
- JsonSerializer.cs
核心组件
- IStorage:定义通用的键值存储操作(读、写、异步读、异步写、存在性检查、删除)。它是所有存储实现的基础契约。
- IFileStorage:面向文件系统的存储接口,继承自 IStorage,强调文件持久化语义。
- IScopedStorage:作用域存储接口,继承自 IStorage,提供命名空间隔离与分组能力。
- ISerializer:序列化器接口,提供对象与字符串之间的双向转换,支撑数据持久化。
章节来源
架构总览
存储系统采用“接口 + 多实现”的分层设计:
- 抽象层定义统一契约,屏蔽平台差异
- 具体实现分别适配 .NET 文件系统与 Godot 平台
- 通过组合序列化器实现数据格式无关性
classDiagram
class IStorage {
+Exists(key) bool
+ExistsAsync(key) Task~bool~
+Read~T~(key) T
+Read~T~(key, defaultValue) T
+ReadAsync~T~(key) Task~T~
+Write~T~(key, value) void
+WriteAsync~T~(key, value) Task
+Delete(key) void
}
class IFileStorage
class IScopedStorage
class ISerializer {
+Serialize~T~(value) string
+Deserialize~T~(data) T
}
class FileStorage {
-rootPath : string
-serializer : ISerializer
-extension : string
+ToPath(key) string
+Exists(key) bool
+ExistsAsync(key) Task~bool~
+Read~T~(key) T
+Read~T~(key, defaultValue) T
+ReadAsync~T~(key) Task~T~
+Write~T~(key, value) void
+WriteAsync~T~(key, value) Task
+Delete(key) void
}
class GodotFileStorage {
+Exists(key) bool
+ExistsAsync(key) Task~bool~
+Read~T~(key) T
+Read~T~(key, defaultValue) T
+ReadAsync~T~(key) Task~T~
+Write~T~(key, value) void
+WriteAsync~T~(key, value) Task
+Delete(key) void
}
class ScopedStorage {
-inner : IStorage
-prefix : string
+Scope(scope) IStorage
+Key(key) string
}
class JsonSerializer {
+Serialize~T~(value) string
+Deserialize~T~(data) T
}
IFileStorage --|> IStorage
IScopedStorage --|> IStorage
FileStorage ..|> IFileStorage
GodotFileStorage ..|> IStorage
ScopedStorage ..|> IScopedStorage
FileStorage --> ISerializer
GodotFileStorage --> ISerializer
JsonSerializer ..|> ISerializer
图表来源
- IStorage.cs
- IFileStorage.cs
- IScopedStorage.cs
- FileStorage.cs
- GodotFileStorage.cs
- ScopedStorage.cs
- ISerializer.cs
- JsonSerializer.cs
组件详解
IStorage 接口
- 设计理念
- 提供跨平台、跨实现的一致性 API
- 明确区分同步与异步操作,便于在不同运行时(.NET、Godot)中高效使用
- 支持默认值读取,降低调用侧的健壮性开销
- 关键方法
- 存在性检查:Exists、ExistsAsync
- 读取:Read、Read(string key, T defaultValue)、ReadAsync
- 写入:Write、WriteAsync
- 删除:Delete
- 扩展机制
- 通过继承 IStorage 可以实现不同介质(文件、内存、网络)的存储
- 通过组合 ISerializer 实现数据格式无关的持久化
章节来源
IFileStorage 接口
- 定义:面向文件系统的存储契约,继承自 IStorage
- 作用:约束文件存储的语义与行为,确保实现遵循文件路径、扩展名、编码等约定
章节来源
IScopedStorage 接口
- 定义:作用域存储接口,继承自 IStorage
- 作用:提供命名空间隔离与分组能力,常用于临时数据、会话数据、模块化数据的逻辑分组
章节来源
FileStorage(.NET 文件系统实现)
- 职责
- 基于本地文件系统实现 IFileStorage
- 将键映射为文件路径,使用序列化器进行数据持久化
- 关键特性
- 路径管理:键中“/”作为目录分隔符;自动清理非法字符;防止路径遍历(禁止“..”)
- 线程安全:按键粒度的锁,提升并发性能
- 编码与扩展:UTF-8 文本读写,默认扩展名“.dat”
- 错误处理:键不存在时读取抛出异常;提供默认值读取避免异常
- 主要方法
- Exists/ExistsAsync:检查文件是否存在
- Read/Read(string key, T defaultValue)/ReadAsync:读取并反序列化
- Write/WriteAsync:序列化并写入
- Delete:删除对应文件
- ToPath:键到路径的映射与校验
flowchart TD
Start(["进入 ToPath(key)"]) --> CheckEmpty["校验 key 是否为空或空白"]
CheckEmpty --> |空| ThrowEmpty["抛出参数异常"]
CheckEmpty --> |非空| Normalize["规范化分隔符 '/'"]
Normalize --> CheckDotDot["检测是否包含 '..'"]
CheckDotDot --> |包含| ThrowDotDot["抛出参数异常"]
CheckDotDot --> |不包含| Split["按 '/' 分割为段"]
Split --> Sanitize["逐段清理非法文件名字符为 '_'"]
Sanitize --> BuildDir["构造目录路径根目录 + 目录段"]
BuildDir --> EnsureDir["确保目录存在"]
EnsureDir --> Combine["拼接文件名最后一段 + 扩展名"]
Combine --> ReturnPath["返回最终路径"]
图表来源
章节来源
ScopedStorage(作用域存储)
- 职责
- 为所有键添加前缀,实现命名空间隔离与逻辑分组
- 透明包装内部 IStorage 实现,保持同步/异步一致性
- 关键特性
- 前缀拼接:Key(key) 将 prefix 与 key 组合为“prefix/key”
- 嵌套作用域:Scope(scope) 返回新的 ScopedStorage,形成多级前缀
- 与底层共享物理存储:不同作用域写入到不同子路径,不产生重复数据
- 典型使用场景
- 临时数据存储:为每帧/每关卡生成唯一作用域
- 会话数据管理:按会话 ID 或玩家 ID 划分作用域
- 模块化数据:将不同模块的数据隔离在各自作用域内
sequenceDiagram
participant Client as "调用方"
participant Scoped as "ScopedStorage"
participant Inner as "内部 IStorage"
participant FS as "文件系统"
Client->>Scoped : Write("level", 5)
Scoped->>Scoped : Key("level") -> "player/level"
Scoped->>Inner : Write("player/level", 5)
Inner->>FS : 写入文件 "player/level.dat"
FS-->>Inner : 成功
Inner-->>Scoped : 完成
Scoped-->>Client : 完成
图表来源
章节来源
ISerializer 与 JsonSerializer
- ISerializer
- 提供泛型 Serialize/Deserialize,解耦存储介质与数据格式
- JsonSerializer
- 基于 JSON.NET 实现,支持复杂对象序列化与反序列化
- 反序列化失败时抛出参数异常,便于上层捕获与处理
章节来源
GodotFileStorage(Godot 平台实现)
- 职责
- 适配 Godot 的虚拟路径系统(res://、user://)与文件系统路径
- 保持与 FileStorage 一致的 API 语义
- 关键特性
- 路径识别:自动判断 Godot 路径并使用 FileAccess/DirAccess
- 线程安全:按键粒度锁,避免并发写入冲突
- 默认值读取:与 FileStorage 一致的行为
- 与 FileStorage 的差异
- 支持 Godot 虚拟路径
- 删除操作在 GodotFileStorage 中已实现(FileStorage 中未实现 Delete)
章节来源
依赖关系分析
- 接口依赖
- IFileStorage、IScopedStorage 均继承自 IStorage,确保统一的 API 表面
- 实现依赖
- FileStorage、GodotFileStorage 直接实现 IStorage
- ScopedStorage 包装任意 IStorage 实现,形成装饰器模式
- FileStorage、GodotFileStorage 依赖 ISerializer 进行数据序列化
- 外部依赖
- GodotFileStorage 依赖 Godot.FileAccess/DirAccess
- JsonSerializer 依赖 Newtonsoft.Json
graph LR
IStorage --> |实现| FileStorage
IStorage --> |实现| GodotFileStorage
IStorage --> |实现| ScopedStorage
IFileStorage --> |实现| FileStorage
IScopedStorage --> |实现| ScopedStorage
FileStorage --> ISerializer
GodotFileStorage --> ISerializer
ISerializer --> JsonSerializer
图表来源
- IStorage.cs
- IFileStorage.cs
- IScopedStorage.cs
- FileStorage.cs
- GodotFileStorage.cs
- ScopedStorage.cs
- ISerializer.cs
- JsonSerializer.cs
章节来源
性能考量
- 线程安全与锁粒度
- FileStorage、GodotFileStorage、ScopedStorage 均采用按键粒度的锁,减少锁竞争,提升并发吞吐
- IO 模式
- FileStorage 的异步读写仍使用锁保护,避免竞态;异步 IO 与锁共存时需注意避免长时间持有锁
- 序列化成本
- JsonSerializer 适合复杂对象;若追求极致性能,可考虑二进制序列化器
- 路径解析
- ToPath/ToAbsolutePath 会进行字符串处理与目录创建,建议在高频路径上避免频繁键变换
[本节为通用性能建议,无需特定文件来源]
故障排查指南
- 常见异常与处理
- 键为空或包含“..”:抛出参数异常,检查键构造逻辑
- 读取不存在的键:FileStorage 的 Read(string key) 抛出文件未找到异常;建议使用 Read(string key, T defaultValue)
- 路径非法字符:自动清理为“_”,确保键命名规范
- 权限不足:确认存储目录具备读写权限
- 调试建议
- 使用 ScopedStorage 为不同模块划分作用域,便于定位问题
- 记录键到路径的映射,结合日志定位文件位置
- 在 Godot 平台使用 user:// 路径进行用户数据持久化,避免 res:// 只读限制
章节来源
结论
GFramework.Storage 系统通过清晰的接口分层与多平台实现,提供了统一、可扩展、可组合的数据持久化方案。借助 ScopedStorage 的作用域隔离与 ISerializer 的格式无关性,开发者可以快速构建配置文件、用户数据、游戏进度等常见存储需求,并在 .NET 与 Godot 平台上获得一致的开发体验。
[本节为总结性内容,无需特定文件来源]
附录
API 参考速查表
- IStorage
- Exists、ExistsAsync:检查键是否存在
- Read、Read(string key, T defaultValue)、ReadAsync:读取值
- Write、WriteAsync:写入值
- Delete:删除键
- IFileStorage:继承 IStorage,面向文件系统
- IScopedStorage:继承 IStorage,提供作用域前缀
- ISerializer:Serialize、Deserialize
章节来源
实践示例(路径指引)
- 基础文件存储
- 作用域存储
- 参考:ScopedStorage 使用示例
- 参考:组合使用示例
- Godot 平台
章节来源