源码-文件系统体系(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)
{
// 自定义文件写入
}
}
实现步骤详解:
- 继承 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 体系,开发者可以实现自定义的文件系统,满足特殊的业务需求。
下一篇:内置文件系统实现
&spm=1001.2101.3001.5002&articleId=162907626&d=1&t=3&u=36554aa71d7749e3aeef2c6a8bad3444)
378

被折叠的 条评论
为什么被折叠?



