03-04-架构篇-文件系统架构(IFileSystem)

文件系统架构(IFileSystem)

篇章 :03-架构篇 阅读时间 :约 35 分钟 前置知识:了解 Runtime 端系统架构


一、引言

本章将深入解析 YooAsset 的文件系统架构(IFileSystem)。文件系统是 YooAsset 实现跨平台资源访问的核心抽象,它通过统一的接口屏蔽了不同平台的差异,提供了灵活、可扩展的文件访问能力。

YooAsset 的文件系统采用了接口抽象 + 多实现的设计模式,开发者可以根据需要选择合适的文件系统实现,也可以自定义文件系统实现特定需求。本章将详细解析 IFileSystem 接口的设计和实现。


二、IFileSystem 接口设计

2.1 IFileSystem 的概念

IFileSystem 是 YooAsset 文件系统的核心接口,定义了文件系统的基本操作。

IFileSystem 的设计目标:

  • 跨平台:提供统一的文件访问接口,屏蔽不同平台的差异
  • 可扩展:支持开发者自定义文件系统实现
  • 灵活性:支持多种文件系统的组合使用

IFileSystem 的接口定义:

csharp 复制代码
public interface IFileSystem
{
    FileSystemType FileSystemType { get; }
    bool RunInEditor { get; }
    
    void OnCreate(string packageName, string rootDirectory);
    void OnDestroy();
    bool Exists(string filePath);
    byte[] ReadFile(string filePath);
    string ReadFileText(string filePath);
    bool WriteFile(string filePath, byte[] fileData);
    bool WriteFile(string filePath, string fileText);
    void DeleteFile(string filePath);
}

FileSystemType 详解:

FileSystemType 标识文件系统的类型,便于调试和区分不同的文件系统实现。

RunInEditor 详解:

RunInEditor 标识文件系统是否在编辑器中运行。某些文件系统(如 WebGL)只能在特定平台运行。

2.2 IFileSystem 的核心方法

IFileSystem 定义了以下核心方法:

生命周期方法:

  • OnCreate:文件系统创建时调用,用于初始化
  • OnDestroy:文件系统销毁时调用,用于清理资源

文件存在检查:

  • Exists:检查文件是否存在

文件读取方法:

  • ReadFile:以字节数组形式读取文件
  • ReadFileText:以文本形式读取文件

文件写入方法:

  • WriteFile:写入字节数组到文件
  • WriteFile:写入文本到文件

文件删除方法:

  • DeleteFile:删除文件

2.3 IFileSystem 与其他模块的关系

IFileSystem 是 Runtime 端多个模块的依赖:

markdown 复制代码
IFileSystem 关系图
├── ResourceManager
│   └── 通过 IFileSystem 读取 Bundle 文件
├── DownloadManager
│   └── 通过 IFileSystem 写入下载的文件
├── CacheSystem
│   └── 通过 IFileSystem 管理缓存文件
└── Provider
    └── 通过 IFileSystem 读取资源文件

ResourceManager 关系详解:

ResourceManager 在加载资源时需要从 IFileSystem 读取 Bundle 文件。IFileSystem 提供了统一的文件访问接口,使 ResourceManager 不需要关心文件位于哪里。

DownloadManager 关系详解:

DownloadManager 在下载资源时需要将下载的文件写入到 IFileSystem。IFileSystem 的 WriteFile 方法支持将文件写入到不同位置。

CacheSystem 关系详解:

CacheSystem 在管理缓存时需要查询、写入、删除缓存文件。IFileSystem 提供了完整的文件操作接口。


三、DefaultBuildinFileSystem

3.1 DefaultBuildinFileSystem 的概念

DefaultBuildinFileSystem 是 YooAsset 内置的默认构建文件系统,用于管理打包时包含在游戏包体内的资源。

DefaultBuildinFileSystem 的特点:

  • 包内资源:管理打包到 StreamingAssets 的资源
  • 只读访问:资源是只读的,不支持写入
  • 快速访问:资源在本地,无需下载

DefaultBuildinFileSystem 的使用场景:

DefaultBuildinFileSystem 适用于以下场景:

  • 游戏的初始资源
  • 不需要热更新的资源
  • 启动时必须可用的资源

3.2 DefaultBuildinFileSystem 的实现

DefaultBuildinFileSystem 的实现基于 Unity 的 StreamingAssets 访问 API:

StreamingAssets 路径详解:

StreamingAssets 是 Unity 的特殊目录,该目录下的文件会原样打包到游戏中。不同平台下 StreamingAssets 的访问方式不同:

  • Editor:Application.streamingAssetsPath
  • Android:通过 UnityWebRequest 访问 jar:file:// 协议
  • iOS:通过 Application.streamingAssetsPath 访问
  • WebGL:通过 UnityWebRequest 访问

DefaultBuildinFileSystem 的关键代码:

csharp 复制代码
public class DefaultBuildinFileSystem : IFileSystem
{
    private string _rootDirectory;
    
    public byte[] ReadFile(string filePath)
    {
        string fullPath = Path.Combine(_rootDirectory, filePath);
        if (File.Exists(fullPath))
        {
            return File.ReadAllBytes(fullPath);
        }
        return null;
    }
    
    public bool Exists(string filePath)
    {
        string fullPath = Path.Combine(_rootDirectory, filePath);
        return File.Exists(fullPath);
    }
}

3.3 DefaultBuildinFileSystem 的局限性

DefaultBuildinFileSystem 存在以下局限性:

跨平台兼容性:

不同平台下 StreamingAssets 的访问方式不同,需要处理 Android 的 jar 协议和 WebGL 的 HTTP 协议。

只读限制:

StreamingAssets 是只读的,不能用于需要写入的场景。

更新困难:

StreamingAssets 中的资源无法单独更新,需要更新整个安装包。


四、DefaultCacheFileSystem

4.1 DefaultCacheFileSystem 的概念

DefaultCacheFileSystem 是 YooAsset 内置的默认缓存文件系统,用于管理缓存到本地磁盘的资源。

DefaultCacheFileSystem 的特点:

  • 可读写:支持文件的读写操作
  • 持久化:文件持久化存储在磁盘上
  • 可清理:支持缓存清理

DefaultCacheFileSystem 的使用场景:

DefaultCacheFileSystem 适用于以下场景:

  • 热更新下载的资源
  • 临时缓存文件
  • 需要持久化的资源

4.2 DefaultCacheFileSystem 的实现

DefaultCacheFileSystem 的实现基于 Unity 的持久化路径(Application.persistentDataPath):

持久化路径详解:

Application.persistentDataPath 是 Unity 提供的可读写路径:

  • Windows:C:/Users/<user>/AppData/LocalLow/<company>/<product>
  • Android:/storage/emulated/0/Android/data/<package>/files
  • iOS:/var/mobile/Containers/Data/Application/<guid>/Documents

DefaultCacheFileSystem 的关键代码:

csharp 复制代码
public class DefaultCacheFileSystem : IFileSystem
{
    private string _rootDirectory;
    
    public byte[] ReadFile(string filePath)
    {
        string fullPath = Path.Combine(_rootDirectory, filePath);
        if (File.Exists(fullPath))
        {
            return File.ReadAllBytes(fullPath);
        }
        return null;
    }
    
    public bool WriteFile(string filePath, byte[] fileData)
    {
        string fullPath = Path.Combine(_rootDirectory, filePath);
        File.WriteAllBytes(fullPath, fileData);
        return true;
    }
}

4.3 DefaultCacheFileSystem 的缓存管理

DefaultCacheFileSystem 配合 CacheSystem 实现缓存管理:

缓存空间管理:

csharp 复制代码
public class CacheSystem
{
    // 检查缓存空间
    public bool CheckCacheSpace(long requiredSize);
    
    // 清理过期缓存
    public void ClearExpiredCache();
    
    // 获取缓存信息
    public CacheInfo GetCacheInfo();
}

缓存清理策略:

  • LRU 策略:清理最久未使用的缓存
  • 容量限制:限制总缓存大小
  • 时间限制:清理超过指定时间的缓存
  • 手动清理:开发者主动清理

五、DefaultWebServerFileSystem

5.1 DefaultWebServerFileSystem 的概念

DefaultWebServerFileSystem 是 YooAsset 内置的默认 Web 服务器文件系统,用于管理从 Web 服务器下载的资源。

DefaultWebServerFileSystem 的特点:

  • 远程访问:从远程服务器下载资源
  • 按需下载:支持按需下载,无需下载所有资源
  • 配合缓存:与 DefaultCacheFileSystem 配合使用

DefaultWebServerFileSystem 的使用场景:

DefaultWebServerFileSystem 适用于以下场景:

  • 热更新资源
  • 大型游戏的资源分发
  • 跨平台资源管理

5.2 DefaultWebServerFileSystem 的实现

DefaultWebServerFileSystem 的实现基于 UnityWebRequest:

UnityWebRequest 详解:

UnityWebRequest 是 Unity 提供的网络请求 API。它支持多种协议(HTTP、HTTPS、FTP 等),可以处理网络请求的发送、接收和错误处理。

DefaultWebServerFileSystem 的关键代码:

csharp 复制代码
public class DefaultWebServerFileSystem : IFileSystem
{
    public byte[] ReadFile(string filePath)
    {
        string url = Path.Combine(_rootDirectory, filePath);
        UnityWebRequest request = UnityWebRequest.Get(url);
        request.SendWebRequest();
        while (!request.isDone) { }
        
        if (request.result == UnityWebRequest.Result.Success)
        {
            return request.downloadHandler.data;
        }
        return null;
    }
}

DefaultWebServerFileSystem 的异步支持:

DefaultWebServerFileSystem 通常与 DefaultCacheFileSystem 配合使用:

  1. 先检查本地缓存(DefaultCacheFileSystem)
  2. 如果缓存不存在,从 Web 服务器下载
  3. 下载完成后写入本地缓存
  4. 后续读取直接从本地缓存读取

六、IFileSystem 组合使用

6.1 多文件系统组合

YooAsset 支持多个文件系统组合使用,常见组合方式:

构建+缓存组合:

csharp 复制代码
// 配置 DefaultBuildinFileSystem 和 DefaultCacheFileSystem
var initParameters = new HostPlayModeParameters();
initParameters.BuildinFileSystemParameters = new FileSystemParameters
{
    FileSystemType = FileSystemType.DefaultBuildin,
};
initParameters.CacheFileSystemParameters = new FileSystemParameters
{
    FileSystemType = FileSystemType.DefaultCache,
};

构建+缓存+Web 组合:

csharp 复制代码
// 配置 DefaultBuildinFileSystem、DefaultCacheFileSystem 和 DefaultWebServerFileSystem
initParameters.BuildinFileSystemParameters = new FileSystemParameters
{
    FileSystemType = FileSystemType.DefaultBuildin,
};
initParameters.CacheFileSystemParameters = new FileSystemParameters
{
    FileSystemType = FileSystemType.DefaultCache,
};
initParameters.DeliveryFileSystemParameters = new FileSystemParameters
{
    FileSystemType = FileSystemType.DefaultWebServer,
};

6.2 资源定位流程

使用多文件系统组合时,资源定位流程如下:

arduino 复制代码
资源定位流程
1. 检查 Buildin FileSystem(包内资源)
   ├── 存在:使用包内资源
   └── 不存在:继续
2. 检查 Cache FileSystem(本地缓存)
   ├── 存在:使用本地缓存
   └── 不存在:继续
3. 从 Web FileSystem(远程服务器)下载
   ├── 下载成功:写入本地缓存,返回资源
   └── 下载失败:返回错误

6.3 文件系统的优先级

YooAsset 通过文件系统优先级控制资源的查找顺序:

  • 高优先级:构建内资源(DefaultBuildinFileSystem)
  • 中优先级:本地缓存(DefaultCacheFileSystem)
  • 低优先级:远程服务器(DefaultWebServerFileSystem)

优先级的意义:

优先级确保了资源的正确访问顺序:

  • 优先使用本地资源(构建内或本地缓存),速度最快
  • 必要时从远程下载,确保资源的最新性

七、自定义文件系统

7.1 自定义文件系统的使用场景

某些场景下,内置文件系统无法满足需求,需要自定义文件系统:

  • 特殊存储介质:如加密磁盘、SSD 等
  • 特殊网络协议:如 P2P、CDN 等
  • 特殊业务需求:如资源压缩、资源合并等

7.2 自定义文件系统的实现步骤

自定义文件系统的实现步骤如下:

  1. 实现 IFileSystem 接口:实现 IFileSystem 接口的所有方法
  2. 注册自定义文件系统:通过 Settings 注册自定义文件系统
  3. 在 Package 初始化时使用:在 Package 初始化参数中指定自定义文件系统

实现 IFileSystem 接口详解:

csharp 复制代码
public class CustomFileSystem : IFileSystem
{
    public FileSystemType FileSystemType => FileSystemType.Custom;
    public bool RunInEditor => false;
    
    public void OnCreate(string packageName, string rootDirectory)
    {
        // 初始化自定义文件系统
    }
    
    public void OnDestroy()
    {
        // 清理资源
    }
    
    public bool Exists(string filePath) { /* 实现 */ }
    public byte[] ReadFile(string filePath) { /* 实现 */ }
    public bool WriteFile(string filePath, byte[] fileData) { /* 实现 */ }
    public void DeleteFile(string filePath) { /* 实现 */ }
}

7.3 自定义文件系统的最佳实践

错误处理:

实现 IFileSystem 时需要妥善处理错误情况,如文件不存在、读写失败等。建议提供详细的错误信息便于调试。

性能优化:

注意 I/O 操作的性能,避免频繁的小文件读写。可以考虑批量读写、缓存等优化策略。

线程安全:

如果 IFileSystem 会在多线程环境中使用,需要考虑线程安全问题。可以使用锁或线程安全的数据结构。

资源清理:

在 OnDestroy 方法中正确清理资源,避免内存泄漏。


八、总结

本章深入解析了 YooAsset 文件系统架构(IFileSystem),包括:

  • IFileSystem 接口设计:定义了统一的文件访问接口
  • DefaultBuildinFileSystem:管理包内资源
  • DefaultCacheFileSystem:管理本地缓存
  • DefaultWebServerFileSystem:管理远程资源
  • 文件系统组合使用:支持多文件系统的灵活组合
  • 自定义文件系统:支持开发者自定义文件系统

文件系统是 YooAsset 跨平台能力的核心抽象,灵活运用文件系统可以实现各种复杂的资源管理需求。


上一篇 :Runtime 端系统架构 下一篇 :通用异步体系(OperationSystem)

相关推荐
甲维斯8 天前
Opus5.5大考!做一个赛车游戏"秋名山车神"
人工智能·游戏开发
鑫鑫哥adam10 天前
一个 1x1 贴图,是怎么炸掉整个热更包的?
unity3d·游戏开发
Behavior11 天前
Unity 手游动态更换 App 图标 — Android 与 iOS 双端技术方案
c#·unity3d·游戏开发
SmalBox11 天前
03-03-架构篇-Runtime加载系统架构
unity3d·游戏开发
SmalBox11 天前
03-02-架构篇-Editor打包系统架构
unity3d·游戏开发
Yeah12711 天前
当 LLM 进入游戏玩法:从收权到放权
游戏开发
Behavior11 天前
Unity 手游 iOS Deep Link 唤醒全流程:从 URL Scheme / Universal Links 到 C# 层参数投递
c#·unity3d·游戏开发
SmalBox11 天前
03-01-架构篇-整体架构总览
unity3d·游戏开发
RobinDevNotes11 天前
用 godot-rust 给 Godot 写 Rust 扩展
rust·游戏开发