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]
380 lines
19 KiB
Markdown
380 lines
19 KiB
Markdown
# 存储系统
|
||
|
||
<cite>
|
||
**本文引用的文件列表**
|
||
- [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)
|
||
- [ISerializer.cs](file://GFramework.Game.Abstractions/serializer/ISerializer.cs)
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs)
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs)
|
||
- [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs)
|
||
- [ReadMe.md](file://GFramework.Game/storage/ReadMe.md)
|
||
- [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs)
|
||
- [CachedStorage.cs](file://GFramework.Game/README.md)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs)
|
||
- [ISettingsPersistence.cs](file://GFramework.Game.Abstractions/setting/ISettingsPersistence.cs)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [组件详解](#组件详解)
|
||
6. [依赖关系分析](#依赖关系分析)
|
||
7. [性能与优化](#性能与优化)
|
||
8. [故障排查指南](#故障排查指南)
|
||
9. [结论](#结论)
|
||
10. [附录](#附录)
|
||
|
||
## 简介
|
||
本文件面向GFramework存储系统,聚焦于FileStorage文件存储实现、ScopedStorage作用域存储策略、以及IStorage/IFileStorage/IScopedStorage接口的设计理念。文档涵盖文件读写流程、路径管理与安全校验、错误处理机制、作用域隔离与命名空间控制、以及在游戏开发中的典型应用场景(配置、存档、临时缓存)。同时提供配置选项、API参考与实践示例,并总结数据持久化的最佳实践、安全性与性能优化建议。
|
||
|
||
## 项目结构
|
||
存储系统由“抽象接口层”“具体实现层”“序列化器层”“应用集成层”组成:
|
||
- 抽象接口层:定义统一的存储契约(IStorage、IFileStorage、IScopedStorage)。
|
||
- 具体实现层:FileStorage(通用文件系统)、ScopedStorage(作用域包装器)、GodotFileStorage(Godot引擎专用)。
|
||
- 序列化器层:ISerializer及JsonSerializer,负责对象与文本的双向转换。
|
||
- 应用集成层:SettingsPersistence等业务组件通过IStorage进行设置的加载/保存/删除。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "抽象接口层"
|
||
IStorage["IStorage 接口"]
|
||
IFileStorage["IFileStorage 接口"]
|
||
IScopedStorage["IScopedStorage 接口"]
|
||
ISerializer["ISerializer 接口"]
|
||
end
|
||
subgraph "实现层"
|
||
FileStorage["FileStorage 实现"]
|
||
ScopedStorage["ScopedStorage 实现"]
|
||
GodotFileStorage["GodotFileStorage 实现"]
|
||
end
|
||
subgraph "序列化器层"
|
||
JsonSerializer["JsonSerializer 实现"]
|
||
end
|
||
subgraph "应用集成层"
|
||
SettingsPersistence["SettingsPersistence 业务组件"]
|
||
end
|
||
IFileStorage --> IStorage
|
||
IScopedStorage --> IStorage
|
||
FileStorage --> IFileStorage
|
||
ScopedStorage --> IScopedStorage
|
||
GodotFileStorage --> IStorage
|
||
FileStorage --> ISerializer
|
||
GodotFileStorage --> ISerializer
|
||
JsonSerializer --> ISerializer
|
||
SettingsPersistence --> IStorage
|
||
```
|
||
|
||
图表来源
|
||
- [IStorage.cs](file://GFramework.Core.Abstractions/storage/IStorage.cs#L1-L72)
|
||
- [IFileStorage.cs](file://GFramework.Game.Abstractions/storage/IFileStorage.cs#L1-L9)
|
||
- [IScopedStorage.cs](file://GFramework.Game.Abstractions/storage/IScopedStorage.cs#L1-L8)
|
||
- [ISerializer.cs](file://GFramework.Game.Abstractions/serializer/ISerializer.cs#L1-L25)
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L1-L99)
|
||
- [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs#L1-L291)
|
||
- [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs#L1-L29)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
|
||
章节来源
|
||
- [IStorage.cs](file://GFramework.Core.Abstractions/storage/IStorage.cs#L1-L72)
|
||
- [IFileStorage.cs](file://GFramework.Game.Abstractions/storage/IFileStorage.cs#L1-L9)
|
||
- [IScopedStorage.cs](file://GFramework.Game.Abstractions/storage/IScopedStorage.cs#L1-L8)
|
||
- [ISerializer.cs](file://GFramework.Game.Abstractions/serializer/ISerializer.cs#L1-L25)
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L1-L99)
|
||
- [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs#L1-L291)
|
||
- [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs#L1-L29)
|
||
- [ReadMe.md](file://GFramework.Game/storage/ReadMe.md#L1-L135)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
|
||
## 核心组件
|
||
- IStorage:统一的存储接口,定义读写、存在检查、异步操作与删除等能力。
|
||
- IFileStorage:面向文件系统的存储接口,继承自IStorage。
|
||
- IScopedStorage:作用域存储接口,继承自IStorage,提供命名空间隔离。
|
||
- FileStorage:基于文件系统的通用实现,支持同步/异步读写、路径安全校验、细粒度锁。
|
||
- ScopedStorage:作用域包装器,为所有键添加前缀,支持嵌套作用域。
|
||
- ISerializer/JsonSerializer:序列化器接口与JSON实现,负责对象与字符串的互转。
|
||
- SettingsPersistence:设置持久化业务组件,基于IStorage实现设置的加载/保存/删除。
|
||
|
||
章节来源
|
||
- [IStorage.cs](file://GFramework.Core.Abstractions/storage/IStorage.cs#L1-L72)
|
||
- [IFileStorage.cs](file://GFramework.Game.Abstractions/storage/IFileStorage.cs#L1-L9)
|
||
- [IScopedStorage.cs](file://GFramework.Game.Abstractions/storage/IScopedStorage.cs#L1-L8)
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L1-L99)
|
||
- [ISerializer.cs](file://GFramework.Game.Abstractions/serializer/ISerializer.cs#L1-L25)
|
||
- [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs#L1-L29)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
|
||
## 架构总览
|
||
存储系统采用“接口抽象 + 多实现 + 装饰器包装”的架构:
|
||
- 接口层提供统一契约,屏蔽具体实现差异。
|
||
- FileStorage/GodotFileStorage分别适配通用文件系统与Godot虚拟路径。
|
||
- ScopedStorage通过装饰器模式为任意IStorage增加命名空间隔离。
|
||
- SettingsPersistence等业务组件仅依赖IStorage,便于替换与扩展。
|
||
|
||
```mermaid
|
||
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 FileStorage
|
||
class ScopedStorage
|
||
class GodotFileStorage
|
||
class ISerializer
|
||
class JsonSerializer
|
||
class SettingsPersistence
|
||
IFileStorage --|> IStorage
|
||
IScopedStorage --|> IStorage
|
||
FileStorage ..|> IFileStorage
|
||
ScopedStorage ..|> IScopedStorage
|
||
GodotFileStorage ..|> IStorage
|
||
FileStorage --> ISerializer
|
||
GodotFileStorage --> ISerializer
|
||
JsonSerializer ..|> ISerializer
|
||
SettingsPersistence --> IStorage
|
||
```
|
||
|
||
图表来源
|
||
- [IStorage.cs](file://GFramework.Core.Abstractions/storage/IStorage.cs#L1-L72)
|
||
- [IFileStorage.cs](file://GFramework.Game.Abstractions/storage/IFileStorage.cs#L1-L9)
|
||
- [IScopedStorage.cs](file://GFramework.Game.Abstractions/storage/IScopedStorage.cs#L1-L8)
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L1-L99)
|
||
- [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs#L1-L291)
|
||
- [ISerializer.cs](file://GFramework.Game.Abstractions/serializer/ISerializer.cs#L1-L25)
|
||
- [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs#L1-L29)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
|
||
## 组件详解
|
||
|
||
### FileStorage 文件存储实现
|
||
- 设计目标:提供基于文件系统的可靠持久化能力,支持同步/异步读写、路径安全校验、细粒度锁保证线程安全。
|
||
- 关键特性:
|
||
- 路径安全:禁止“..”路径逃逸;清理非法文件名字符;自动创建目录。
|
||
- 锁机制:按路径生成独立锁对象,避免跨键竞争,提升并发性能。
|
||
- 序列化:通过ISerializer完成对象与字符串的转换。
|
||
- 扩展名:默认“.dat”,可通过构造参数定制。
|
||
- 主要方法与流程:
|
||
- 路径转换ToPath:规范化分隔符、清理段名、拼接根路径与扩展名。
|
||
- 读取Read/ReadAsync:先加锁,再读取文件内容,最后反序列化。
|
||
- 写入Write/WriteAsync:先序列化,再加锁写入文件。
|
||
- 存在检查Exists/ExistsAsync:加锁判断文件是否存在。
|
||
- 删除Delete:加锁删除文件。
|
||
- 错误处理:
|
||
- 读取不存在键时抛出FileNotFoundException。
|
||
- 读取重载Read<T>(key, defaultValue)提供默认值避免异常。
|
||
- 路径校验失败抛出ArgumentException。
|
||
- 性能要点:
|
||
- 异步读写仍需加锁,但IO可异步进行,减少阻塞。
|
||
- 并发访问不同键可并行,同一键串行执行。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["调用 Read<T>(key)"]) --> ToPath["ToPath(key)<br/>规范化/清理/拼接路径"]
|
||
ToPath --> Lock["获取/创建键级锁"]
|
||
Lock --> CheckExist{"文件存在?"}
|
||
CheckExist --> |否| ThrowErr["抛出 FileNotFoundException"]
|
||
CheckExist --> |是| ReadFile["读取文件内容"]
|
||
ReadFile --> Deserialize["反序列化为 T"]
|
||
Deserialize --> Return["返回结果"]
|
||
ThrowErr --> End(["结束"])
|
||
Return --> End
|
||
```
|
||
|
||
图表来源
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L144-L157)
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L200-L209)
|
||
|
||
章节来源
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [ReadMe.md](file://GFramework.Game/storage/ReadMe.md#L1-L135)
|
||
|
||
### ScopedStorage 作用域存储策略
|
||
- 设计目标:通过前缀为所有键添加命名空间隔离,实现逻辑分组与数据范围控制,支持嵌套作用域。
|
||
- 关键特性:
|
||
- 前缀拼接:Key(key)将prefix与key组合为“prefix/key”。
|
||
- 嵌套作用域:Scope(scope)返回新的ScopedStorage,前缀叠加。
|
||
- 透明包装:所有IStorage操作均转发到底层inner存储。
|
||
- 同步/异步:与底层存储保持一致的异步能力。
|
||
- 使用场景:
|
||
- 将玩家数据、游戏存档、全局设置分组到不同作用域,避免键冲突。
|
||
- 嵌套作用域用于更细粒度的组织(如settings/audio/master_volume)。
|
||
- 注意事项:
|
||
- 前缀为空时直接使用原键。
|
||
- 与底层存储共享物理存储,注意键冲突与命名规范。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Client as "客户端"
|
||
participant Scoped as "ScopedStorage"
|
||
participant Inner as "内部存储(IStorage)"
|
||
Client->>Scoped : Write(key, value)
|
||
Scoped->>Scoped : Key(key) -> "prefix/key"
|
||
Scoped->>Inner : Write("prefix/key", value)
|
||
Inner-->>Scoped : 完成
|
||
Scoped-->>Client : 返回
|
||
```
|
||
|
||
图表来源
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L63-L73)
|
||
|
||
章节来源
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L1-L99)
|
||
- [ReadMe.md](file://GFramework.Game/storage/ReadMe.md#L60-L121)
|
||
|
||
### 接口设计:IStorage/IFileStorage/IScopedStorage
|
||
- IStorage:定义统一的读写、存在检查、异步与删除能力,是所有存储实现的基础契约。
|
||
- IFileStorage:面向文件系统的扩展接口,强调文件语义(扩展名、路径等)。
|
||
- IScopedStorage:强调命名空间隔离与作用域管理,便于多模块/多功能的数据分区。
|
||
- 设计理念:
|
||
- 抽象先行:通过接口屏蔽实现细节,便于替换与扩展。
|
||
- 统一契约:所有实现遵循相同的API,降低学习成本与迁移成本。
|
||
- 可组合:通过装饰器(如ScopedStorage)增强功能,不侵入核心实现。
|
||
|
||
章节来源
|
||
- [IStorage.cs](file://GFramework.Core.Abstractions/storage/IStorage.cs#L1-L72)
|
||
- [IFileStorage.cs](file://GFramework.Game.Abstractions/storage/IFileStorage.cs#L1-L9)
|
||
- [IScopedStorage.cs](file://GFramework.Game.Abstractions/storage/IScopedStorage.cs#L1-L8)
|
||
|
||
### 序列化器:ISerializer/JsonSerializer
|
||
- ISerializer:定义Serialize/Deserialize通用方法,解耦存储与序列化技术。
|
||
- JsonSerializer:基于Newtonsoft.Json实现,提供对象与JSON字符串的互转。
|
||
- 使用建议:
|
||
- 选择与数据结构匹配的序列化器(JSON适合结构化数据;二进制/自定义格式适合性能敏感场景)。
|
||
- 注意反序列化失败时的异常处理与默认值策略。
|
||
|
||
章节来源
|
||
- [ISerializer.cs](file://GFramework.Game.Abstractions/serializer/ISerializer.cs#L1-L25)
|
||
- [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs#L1-L29)
|
||
|
||
### 应用集成:SettingsPersistence
|
||
- 通过IStorage实现设置的异步加载、保存、存在检查与删除。
|
||
- 与事件系统配合,发出加载/应用/保存等事件,便于观察状态变化。
|
||
- 适用于游戏配置、音量、难度等设置的持久化管理。
|
||
|
||
章节来源
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
- [ISettingsPersistence.cs](file://GFramework.Game.Abstractions/setting/ISettingsPersistence.cs#L1-L43)
|
||
|
||
## 依赖关系分析
|
||
- FileStorage依赖ISerializer进行序列化;依赖路径工具与文件系统API;使用ConcurrentDictionary维护键级锁。
|
||
- ScopedStorage依赖IStorage,通过装饰器模式透明包装任何存储实现。
|
||
- SettingsPersistence依赖IStorage与事件系统,实现设置的生命周期管理。
|
||
- GodotFileStorage为Godot引擎特化实现,兼容res://与user://虚拟路径,提供Godot FileAccess支持。
|
||
|
||
```mermaid
|
||
graph LR
|
||
FileStorage --> ISerializer
|
||
ScopedStorage --> IStorage
|
||
GodotFileStorage --> ISerializer
|
||
SettingsPersistence --> IStorage
|
||
```
|
||
|
||
图表来源
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L1-L99)
|
||
- [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs#L1-L291)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
|
||
章节来源
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [ScopedStorage.cs](file://GFramework.Game/storage/ScopedStorage.cs#L1-L99)
|
||
- [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs#L1-L291)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
|
||
## 性能与优化
|
||
- 并发与锁:
|
||
- FileStorage按键级锁,不同键可并行;同一键串行,避免竞态。
|
||
- GodotFileStorage同理,按键级锁保障线程安全。
|
||
- 异步IO:
|
||
- FileStorage/ScopedStorage在读取时可使用异步IO(注意锁范围)。
|
||
- GodotFileStorage ReadAsync通过Task.Run包装同步读取,简化调用。
|
||
- 缓存策略:
|
||
- 可使用CachedStorage对热点数据进行内存缓存,减少重复IO。
|
||
- 缓存过期时间可配置,默认5分钟;支持清空缓存与清空存储。
|
||
- 写入优化:
|
||
- 批量写入优于频繁小写入;可缓冲后再一次性写入。
|
||
- 合理拆分键层级,避免单文件过大导致读写压力集中。
|
||
- 路径与序列化:
|
||
- 使用合理扩展名与目录结构,便于备份与迁移。
|
||
- 选择合适的序列化器,平衡可读性、体积与性能。
|
||
|
||
章节来源
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L1-L258)
|
||
- [GodotFileStorage.cs](file://GFramework.Godot/storage/GodotFileStorage.cs#L1-L291)
|
||
- [CachedStorage.cs](file://GFramework.Game/README.md#L550-L647)
|
||
|
||
## 故障排查指南
|
||
- 常见问题与定位:
|
||
- “存储键不存在”:FileStorage读取会抛出FileNotFoundException;建议使用Read<T>(key, defaultValue)提供默认值。
|
||
- “路径包含‘..’”:ToPath会拒绝包含“..”的键,抛出ArgumentException;请使用合法路径。
|
||
- “文件名包含非法字符”:SanitizeSegment会替换非法字符为下划线;请避免使用不可用字符。
|
||
- “权限不足”:确保程序对存储目录具有读写权限。
|
||
- “序列化失败”:JsonSerializer反序列化失败会抛出ArgumentException;检查数据格式与字段映射。
|
||
- 调试建议:
|
||
- 在关键节点记录日志(键、路径、序列化前后大小)。
|
||
- 使用ScopedStorage隔离不同模块,缩小问题范围。
|
||
- 对高频读写键进行缓存,减少IO波动。
|
||
|
||
章节来源
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L55-L103)
|
||
- [FileStorage.cs](file://GFramework.Game/storage/FileStorage.cs#L144-L157)
|
||
- [JsonSerializer.cs](file://GFramework.Game/serializer/JsonSerializer.cs#L20-L29)
|
||
|
||
## 结论
|
||
GFramework存储系统通过清晰的接口抽象与多种实现,为游戏开发提供了灵活、安全且高性能的数据持久化方案。FileStorage提供通用文件存储能力,ScopedStorage实现命名空间隔离与作用域管理,ISerializer解耦序列化技术,SettingsPersistence将存储与业务流程结合。配合缓存与异步IO策略,可在保证一致性的同时提升性能与可维护性。
|
||
|
||
## 附录
|
||
|
||
### API参考(IStorage/IFileStorage/IScopedStorage)
|
||
- IStorage
|
||
- Exists(key): 检查键是否存在
|
||
- ExistsAsync(key): 异步检查
|
||
- Read<T>(key): 读取键值
|
||
- Read<T>(key, defaultValue): 读取键值或默认值
|
||
- ReadAsync<T>(key): 异步读取
|
||
- Write<T>(key, value): 写入键值
|
||
- WriteAsync<T>(key, value): 异步写入
|
||
- Delete(key): 删除键
|
||
- IFileStorage:继承IStorage,面向文件系统
|
||
- IScopedStorage:继承IStorage,提供作用域包装
|
||
|
||
章节来源
|
||
- [IStorage.cs](file://GFramework.Core.Abstractions/storage/IStorage.cs#L1-L72)
|
||
- [IFileStorage.cs](file://GFramework.Game.Abstractions/storage/IFileStorage.cs#L1-L9)
|
||
- [IScopedStorage.cs](file://GFramework.Game.Abstractions/storage/IScopedStorage.cs#L1-L8)
|
||
|
||
### 配置与使用示例
|
||
- FileStorage
|
||
- 构造:FileStorage(rootPath, serializer, extension=".dat")
|
||
- 示例:写入/读取/异步读取/存在检查/删除
|
||
- ScopedStorage
|
||
- 构造:ScopedStorage(inner, prefix)
|
||
- 示例:作用域前缀、嵌套作用域、异步操作
|
||
- SettingsPersistence
|
||
- 异步加载/保存/存在检查/删除;发送事件通知
|
||
|
||
章节来源
|
||
- [ReadMe.md](file://GFramework.Game/storage/ReadMe.md#L1-L135)
|
||
- [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs#L1-L39)
|
||
|
||
### 最佳实践
|
||
- 命名与分层:使用有意义的键层级与作用域,避免键冲突。
|
||
- 默认值策略:读取时提供默认值,避免异常传播。
|
||
- 缓存与批处理:对热点数据启用缓存;合并多次写入为批量写入。
|
||
- 安全与合规:严格校验键与路径,避免路径逃逸;定期备份重要数据。
|
||
- 性能监控:关注IO延迟与锁等待,必要时引入异步与缓存。 |