06-01-YooAsset源码-Unity文件系统体系(IFileSystem)

源码-文件系统体系(IFileSystem)

篇章:06-源码深度-文件系统与下载模块
阅读时间:约 25 分钟
前置知识:了解运行时核心模块


一、引言

本章将深入解析 YooAsset 文件系统体系(IFileSystem)的源码实现。IFileSystem 是 YooAsset 文件系统的核心抽象,提供了跨平台的文件访问能力。深入理解 IFileSystem 是掌握 YooAsset 跨平台资源管理能力的关键。

IFileSystem 的设计目标是提供统一、可扩展、跨平台的文件访问接口。本章将从源码层面深入解析 IFileSystem 体系的设计和实现。


二、IFileSystem 接口

2.1 IFileSystem 接口定义

IFileSystem 是 YooAsset 文件系统的核心接口:

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 标识文件系统是否在 Editor 中运行。

OnCreate 详解

OnCreate 是文件系统的创建回调,用于初始化文件系统。

OnDestroy 详解

OnDestroy 是文件系统的销毁回调,用于清理资源。

核心方法详解

  • Exists:检查文件是否存在
  • ReadFile:读取文件字节数据
  • ReadFileText:读取文件文本
  • WriteFile:写入文件
  • DeleteFile:删除文件

2.2 文件系统的实现

YooAsset 提供了多种 IFileSystem 实现:

public abstract class FileSystemBase : IFileSystem
{
    public abstract FileSystemType FileSystemType { get; }
    public abstract bool RunInEditor { get; }
    public string PackageName { get; protected set; }
    public string RootDirectory { get; protected set; }
    
    public virtual void OnCreate(string packageName, string rootDirectory)
    {
        PackageName = packageName;
        RootDirectory = rootDirectory;
    }
    
    public virtual void OnDestroy() { }
    
    public abstract bool Exists(string filePath);
    public abstract byte[] ReadFile(string filePath);
    public abstract string ReadFileText(string filePath);
    public abstract bool WriteFile(string filePath, byte[] fileData);
    public abstract bool WriteFile(string filePath, string fileText);
    public abstract void DeleteFile(string filePath);
}

FileSystemBase 详解

FileSystemBase 是 IFileSystem 的抽象基类,提供了通用的字段和实现。

抽象方法详解

具体的文件系统继承 FileSystemBase 并实现抽象方法。

2.3 文件系统的创建

public class FileSystemFactory
{
    public static IFileSystem CreateFileSystem(EFileSystemType type, string packageName, string rootDirectory)
    {
        IFileSystem fileSystem;
        switch (type)
        {
            case EFileSystemType.DefaultBuildin:
                fileSystem = new DefaultBuildinFileSystem();
                break;
            case EFileSystemType.DefaultCache:
                fileSystem = new DefaultCacheFileSystem();
                break;
            case EFileSystemType.DefaultDelivery:
                fileSystem = new DefaultDeliveryFileSystem();
                break;
            default:
                throw new Exception($"Unknown file system type: {type}");
        }
        fileSystem.OnCreate(packageName, rootDirectory);
        return fileSystem;
    }
}

工厂模式详解

使用工厂模式创建不同类型的文件系统。

创建流程详解

根据类型创建对应的文件系统实例,调用 OnCreate 初始化。


三、内置文件系统

3.1 StreamingAssetsFileSystem

StreamingAssetsFileSystem 是基于 Unity StreamingAssets 的文件系统:

public class DefaultBuildinFileSystem : FileSystemBase
{
    public override FileSystemType FileSystemType => FileSystemType.DefaultBuildin;
    public override bool RunInEditor => true;
    
    public override bool Exists(string filePath)
    {
        string fullPath = Path.Combine(RootDirectory, filePath);
        return File.Exists(fullPath);
    }
    
    public override byte[] ReadFile(string filePath)
    {
        string fullPath = Path.Combine(RootDirectory, filePath);
        if (File.Exists(fullPath))
            return File.ReadAllBytes(fullPath);
        return null;
    }
}

StreamingAssets 路径详解

StreamingAssets 路径在不同平台下不同:

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

适用场景详解

适用于打包在游戏包体内的资源,只读访问。

3.2 PersistentFileSystem

PersistentFileSystem 是基于 Unity persistentDataPath 的文件系统:

public class DefaultCacheFileSystem : FileSystemBase
{
    public override FileSystemType FileSystemType => FileSystemType.DefaultCache;
    public override bool RunInEditor => true;
    
    public override bool Exists(string filePath)
    {
        string fullPath = Path.Combine(RootDirectory, filePath);
        return File.Exists(fullPath);
    }
    
    public override byte[] ReadFile(string filePath)
    {
        string fullPath = Path.Combine(RootDirectory, filePath);
        if (File.Exists(fullPath))
            return File.ReadAllBytes(fullPath);
        return null;
    }
    
    public override bool WriteFile(string filePath, byte[] fileData)
    {
        string fullPath = Path.Combine(RootDirectory, filePath);
        File.WriteAllBytes(fullPath, fileData);
        return true;
    }
}

persistentDataPath 路径详解

persistentDataPath 在不同平台下不同:

  • Windows:%USERPROFILE%/AppData/LocalLow/<company>/<product>
  • macOS:~/Library/Application Support/<company>/<product>
  • iOS:<Application>/Documents/
  • Android:/storage/emulated/0/Android/data/<package>/files

适用场景详解

适用于持久化存储的资源,可读写。

3.3 WebFileSystem

WebFileSystem 是基于 Web 平台的文件系统:

public class DefaultDeliveryFileSystem : FileSystemBase
{
    public override FileSystemType FileSystemType => FileSystemType.DefaultDelivery;
    public override bool RunInEditor => false;
    
    public override bool Exists(string filePath)
    {
        // 通过 HTTP HEAD 请求检查
        var request = UnityWebRequest.Head(GetFileURL(filePath));
        request.SendWebRequest();
        while (!request.isDone) { }
        return request.result == UnityWebRequest.Result.Success;
    }
    
    public override byte[] ReadFile(string filePath)
    {
        var request = UnityWebRequest.Get(GetFileURL(filePath));
        request.SendWebRequest();
        while (!request.isDone) { }
        
        if (request.result == UnityWebRequest.Result.Success)
            return request.downloadHandler.data;
        return null;
    }
}

WebGL 限制详解

WebGL 平台不支持本地文件访问,所有资源都需要从远程加载。

IndexedDB 缓存详解

WebGL 平台可以使用 IndexedDB 实现本地缓存,但性能较差。

适用场景详解

适用于 WebGL、小游戏等 Web 平台。

3.4 RawFileFileSystem

RawFileFileSystem 是基于 Resources 目录的文件系统:

public class RawFileSystem : FileSystemBase
{
    public override FileSystemType FileSystemType => FileSystemType.RawFile;
    public override bool RunInEditor => true;
    
    public override byte[] ReadFile(string filePath)
    {
        TextAsset textAsset = Resources.Load<TextAsset>(filePath);
        if (textAsset != null)
            return textAsset.bytes;
        return null;
    }
}

Resources 目录详解

Resources 目录是 Unity 的特殊目录,可以通过 Resources.Load 加载资源。

RawFile 概念详解

RawFile 是 Unity 的原生文件,不会被 Unity 处理。

适用场景详解

适用于不需要打 AssetBundle 的原生文件。


四、自定义文件系统

4.1 自定义文件系统的应用场景

某些场景下需要自定义文件系统:

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

4.2 自定义文件系统的实现

public class CustomFileSystem : FileSystemBase
{
    public override FileSystemType FileSystemType => FileSystemType.Custom;
    public override bool RunInEditor => false;
    
    public override void OnCreate(string packageName, string rootDirectory)
    {
        base.OnCreate(packageName, rootDirectory);
        // 初始化自定义文件系统
    }
    
    public override bool Exists(string filePath)
    {
        // 自定义文件存在检查
    }
    
    public override byte[] ReadFile(string filePath)
    {
        // 自定义文件读取
    }
    
    public override bool WriteFile(string filePath, byte[] fileData)
    {
        // 自定义文件写入
    }
}

实现步骤详解

  1. 继承 FileSystemBase
  2. 实现所有抽象方法
  3. 注册到 FileSystemFactory
  4. 在 Package 初始化时使用

4.3 接入第三方云存储

public class S3FileSystem : FileSystemBase
{
    private AmazonS3Client _s3Client;
    
    public override void OnCreate(string packageName, string rootDirectory)
    {
        base.OnCreate(packageName, rootDirectory);
        _s3Client = new AmazonS3Client(accessKey, secretKey, region);
    }
    
    public override byte[] ReadFile(string filePath)
    {
        var request = new GetObjectRequest
        {
            BucketName = "my-bucket",
            Key = $"{PackageName}/{filePath}"
        };
        
        var response = _s3Client.GetObjectAsync(request).Result;
        using (var stream = response.ResponseStream)
        using (var memoryStream = new MemoryStream())
        {
            stream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }
    }
}

AWS S3 接入详解

使用 AWS SDK 接入 S3,实现文件读取和写入。

OSS 接入详解

使用阿里云 OSS SDK 接入 OSS。

COS 接入详解

使用腾讯云 COS SDK 接入 COS。

4.4 加密文件系统

public class EncryptedFileSystem : FileSystemBase
{
    private IFileSystem _innerFileSystem;
    private byte[] _encryptionKey;
    
    public override byte[] ReadFile(string filePath)
    {
        byte[] encryptedData = _innerFileSystem.ReadFile(filePath);
        if (encryptedData == null) return null;
        return Decrypt(encryptedData, _encryptionKey);
    }
    
    public override bool WriteFile(string filePath, byte[] fileData)
    {
        byte[] encryptedData = Encrypt(fileData, _encryptionKey);
        return _innerFileSystem.WriteFile(filePath, encryptedData);
    }
}

加密读取详解

读取文件后解密数据。

加密写入详解

写入文件前加密数据。

包装器模式详解

加密文件系统通过包装其他文件系统实现。


五、文件系统组合

5.1 多文件系统组合

YooAsset 支持多个文件系统组合使用:

public class ResourcePackage
{
    public IFileSystem BuildinFileSystem;
    public IFileSystem CacheFileSystem;
    public IFileSystem DeliveryFileSystem;
}

三个文件系统详解

  • BuildinFileSystem:包内资源
  • CacheFileSystem:本地缓存
  • DeliveryFileSystem:远程资源

5.2 资源查找流程

public class ResourcePackage
{
    public byte[] ReadFile(string filePath)
    {
        // 1. 优先从 Buildin 读取
        var data = BuildinFileSystem.ReadFile(filePath);
        if (data != null) return data;
        
        // 2. 然后从 Cache 读取
        data = CacheFileSystem.ReadFile(filePath);
        if (data != null) return data;
        
        // 3. 最后从 Delivery 读取
        data = DeliveryFileSystem.ReadFile(filePath);
        if (data != null)
        {
            // 缓存到 Cache
            CacheFileSystem.WriteFile(filePath, data);
        }
        return data;
    }
}

优先级详解

资源查找的优先级是 Buildin > Cache > Delivery。

缓存机制详解

从 Delivery 加载的资源会缓存到 Cache,下次直接从 Cache 读取。

5.3 文件系统的初始化

public class ResourcePackage
{
    public void InitFileSystems(string buildinRoot, string cacheRoot, string deliveryRoot)
    {
        BuildinFileSystem = FileSystemFactory.CreateFileSystem(
            EFileSystemType.DefaultBuildin, PackageName, buildinRoot);
        CacheFileSystem = FileSystemFactory.CreateFileSystem(
            EFileSystemType.DefaultCache, PackageName, cacheRoot);
        DeliveryFileSystem = FileSystemFactory.CreateFileSystem(
            EFileSystemType.DefaultDelivery, PackageName, deliveryRoot);
    }
}

初始化流程详解

根据配置创建三个文件系统实例。


六、总结

本章深入解析了 YooAsset 文件系统体系(IFileSystem)的源码实现,包括:

  • IFileSystem 接口:核心接口定义、内置实现
  • 内置文件系统:StreamingAssetsFileSystem、PersistentFileSystem、WebFileSystem、RawFileFileSystem
  • 自定义文件系统:实现步骤、第三方云存储接入、加密文件系统
  • 文件系统组合:多文件系统组合、资源查找流程、初始化

通过深入理解 IFileSystem 体系,开发者可以实现自定义的文件系统,满足特殊的业务需求。


下一篇内置文件系统实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡海水

感谢支持 共同进步 好运++

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值