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 StreamingAssetsFileSystemStreamingAssetsFileSystem 是基于 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 路径在不同平台下不同EditorApplication.streamingAssetsPathAndroid通过 UnityWebRequest 访问 jar:file://iOSApplication.streamingAssetsPathWebGL通过 UnityWebRequest 访问 HTTP适用场景详解适用于打包在游戏包体内的资源只读访问。3.2 PersistentFileSystemPersistentFileSystem 是基于 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/productmacOS~/Library/Application Support/company/productiOSApplication/Documents/Android/storage/emulated/0/Android/data/package/files适用场景详解适用于持久化存储的资源可读写。3.3 WebFileSystemWebFileSystem 是基于 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 RawFileFileSystemRawFileFileSystem 是基于 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.LoadTextAsset(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) { // 自定义文件写入 } }实现步骤详解继承 FileSystemBase实现所有抽象方法注册到 FileSystemFactory在 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 体系开发者可以实现自定义的文件系统满足特殊的业务需求。下一篇内置文件系统实现