Add clear unused cache files method.

增加清空缓存文件的方法。
pull/9/head
hevinci 2022-05-02 15:03:36 +08:00
parent 2c9819762a
commit 873d873194
12 changed files with 191 additions and 162 deletions

View File

@ -112,7 +112,7 @@ namespace YooAsset
{ {
if (_cachedHashList.ContainsKey(hash)) if (_cachedHashList.ContainsKey(hash))
{ {
string filePath = SandboxHelper.MakeSandboxCacheFilePath(hash); string filePath = SandboxHelper.MakeCacheFilePath(hash);
if (File.Exists(filePath)) if (File.Exists(filePath))
{ {
return true; return true;
@ -150,7 +150,7 @@ namespace YooAsset
} }
public static bool CheckContentIntegrity(PatchBundle patchBundle) public static bool CheckContentIntegrity(PatchBundle patchBundle)
{ {
string filePath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash); string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.Hash);
return CheckContentIntegrity(filePath, patchBundle.SizeBytes, patchBundle.CRC); return CheckContentIntegrity(filePath, patchBundle.SizeBytes, patchBundle.CRC);
} }
public static bool CheckContentIntegrity(string filePath, long size, string crc) public static bool CheckContentIntegrity(string filePath, long size, string crc)

View File

@ -25,12 +25,12 @@ namespace YooAsset
/// <summary> /// <summary>
/// 远端下载地址 /// 远端下载地址
/// </summary> /// </summary>
public string RemoteMainURL { private set; get; } internal string RemoteMainURL { private set; get; }
/// <summary> /// <summary>
/// 远端下载备用地址 /// 远端下载备用地址
/// </summary> /// </summary>
public string RemoteFallbackURL { private set; get; } internal string RemoteFallbackURL { private set; get; }
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值
@ -103,49 +103,6 @@ namespace YooAsset
} }
/// <summary>
/// 资源包是否有效
/// </summary>
public bool IsValid()
{
return _patchBundle != null;
}
/// <summary>
/// 资源包文件是否在云端
/// </summary>
public bool InCloud()
{
return LoadMode == ELoadMode.LoadFromRemote;
}
/// <summary>
/// 获取流文件夹的加载路径
/// </summary>
public string GetStreamingLoadPath()
{
if (_patchBundle == null)
return string.Empty;
if (string.IsNullOrEmpty(_streamingPath))
_streamingPath = PathHelper.MakeStreamingLoadPath(_patchBundle.Hash);
return _streamingPath;
}
/// <summary>
/// 获取缓存文件夹的加载路径
/// </summary>
public string GetCacheLoadPath()
{
if (_patchBundle == null)
return string.Empty;
if (string.IsNullOrEmpty(_cachePath))
_cachePath = SandboxHelper.MakeSandboxCacheFilePath(_patchBundle.Hash);
return _cachePath;
}
private BundleInfo() private BundleInfo()
{ {
} }
@ -174,6 +131,49 @@ namespace YooAsset
RemoteFallbackURL = string.Empty; RemoteFallbackURL = string.Empty;
} }
/// <summary>
/// 资源包是否有效
/// </summary>
public bool IsValid()
{
return _patchBundle != null;
}
/// <summary>
/// 资源包文件是否在云端
/// </summary>
public bool InCloud()
{
return LoadMode == ELoadMode.LoadFromRemote;
}
/// <summary>
/// 获取流文件夹的加载路径
/// </summary>
internal string GetStreamingLoadPath()
{
if (_patchBundle == null)
return string.Empty;
if (string.IsNullOrEmpty(_streamingPath))
_streamingPath = PathHelper.MakeStreamingLoadPath(_patchBundle.Hash);
return _streamingPath;
}
/// <summary>
/// 获取缓存文件夹的加载路径
/// </summary>
internal string GetCacheLoadPath()
{
if (_patchBundle == null)
return string.Empty;
if (string.IsNullOrEmpty(_cachePath))
_cachePath = SandboxHelper.MakeCacheFilePath(_patchBundle.Hash);
return _cachePath;
}
/// <summary> /// <summary>
/// 是否为JAR包内文件 /// 是否为JAR包内文件
/// </summary> /// </summary>

View File

@ -0,0 +1,60 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace YooAsset
{
[Serializable]
internal sealed class CacheData
{
/// <summary>
/// 缓存的APP内置版本
/// </summary>
public string CacheAppVersion = string.Empty;
/// <summary>
/// 读取缓存文件
/// 注意:如果文件不存在则创建新的缓存文件
/// </summary>
public static CacheData LoadCache()
{
string filePath = GetCacheDataFilePath();
if (File.Exists(filePath))
{
string jsonData = FileUtility.ReadFile(filePath);
var cacheData = JsonUtility.FromJson<CacheData>(jsonData);
YooLogger.Log($"Load cache data : {cacheData.CacheAppVersion}");
return cacheData;
}
else
{
YooLogger.Log($"Create cache data : {Application.version}");
CacheData cacheData = new CacheData();
cacheData.CacheAppVersion = Application.version;
string jsonData = JsonUtility.ToJson(cacheData);
FileUtility.CreateFile(filePath, jsonData);
return cacheData;
}
}
/// <summary>
/// 更新缓存文件
/// </summary>
public static void UpdateCache()
{
YooLogger.Log($"Update cache data to disk : {Application.version}");
CacheData cacheData = new CacheData();
cacheData.CacheAppVersion = Application.version;
string filePath = GetCacheDataFilePath();
string jsonData = JsonUtility.ToJson(cacheData);
FileUtility.CreateFile(filePath, jsonData);
}
private static string GetCacheDataFilePath()
{
return PathHelper.MakePersistentLoadPath("CacheData.bytes");
}
}
}

View File

@ -53,7 +53,7 @@ namespace YooAsset
{ {
if (_steps == ESteps.None || _steps == ESteps.Done) if (_steps == ESteps.None || _steps == ESteps.Done)
return; return;
if (_steps == ESteps.Update) if (_steps == ESteps.Update)
{ {
_appManifestLoader.Update(); _appManifestLoader.Update();
@ -61,7 +61,7 @@ namespace YooAsset
return; return;
if (_appManifestLoader.Result == null) if (_appManifestLoader.Result == null)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = _appManifestLoader.Error; Error = _appManifestLoader.Error;
@ -110,20 +110,20 @@ namespace YooAsset
if (_steps == ESteps.InitCache) if (_steps == ESteps.InitCache)
{ {
// 每次启动时比对APP版本号是否一致 // 每次启动时比对APP版本号是否一致
PatchCache cache = PatchCache.LoadCache(); CacheData cacheData = CacheData.LoadCache();
if (cache.CacheAppVersion != Application.version) if (cacheData.CacheAppVersion != Application.version)
{ {
YooLogger.Warning($"Cache is dirty ! Cache app version is {cache.CacheAppVersion}, Current app version is {Application.version}"); YooLogger.Warning($"Cache is dirty ! Cache application version is {cacheData.CacheAppVersion}, Current application version is {Application.version}");
// 注意在覆盖安装的时候会保留APP沙盒目录可以选择清空缓存目录 // 注意在覆盖安装的时候会保留APP沙盒目录可以选择清空缓存目录
if (_impl.ClearCacheWhenDirty) if (_impl.ClearCacheWhenDirty)
{ {
YooLogger.Warning("Clear cache files."); YooLogger.Warning("Clear cache files.");
SandboxHelper.DeleteSandboxCacheFolder(); SandboxHelper.DeleteCacheFolder();
} }
// 更新缓存文件 // 更新缓存文件
PatchCache.UpdateCache(); CacheData.UpdateCache();
} }
_steps = ESteps.Update; _steps = ESteps.Update;
} }
@ -243,7 +243,7 @@ namespace YooAsset
if (_downloader2.HasError()) if (_downloader2.HasError())
{ {
Error = _downloader2.GetError(); Error = _downloader2.GetError();
_steps = ESteps.Failed; _steps = ESteps.Failed;
} }
else else

View File

@ -277,7 +277,7 @@ namespace YooAsset
} }
// 查看文件是否存在 // 查看文件是否存在
string filePath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash); string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.Hash);
if (File.Exists(filePath) == false) if (File.Exists(filePath) == false)
continue; continue;
@ -321,7 +321,7 @@ namespace YooAsset
} }
private bool RunThread(PatchBundle patchBundle) private bool RunThread(PatchBundle patchBundle)
{ {
string filePath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash); string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.Hash);
ThreadInfo info = new ThreadInfo(filePath, patchBundle); ThreadInfo info = new ThreadInfo(filePath, patchBundle);
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), info); return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), info);
} }

View File

@ -210,7 +210,7 @@ namespace YooAsset
// 注意:下载系统只会验证当前游戏版本的资源文件,对于其它游戏版本的差异文件不会在初始化的时候去做校验。 // 注意:下载系统只会验证当前游戏版本的资源文件,对于其它游戏版本的差异文件不会在初始化的时候去做校验。
// 注意:通过比对文件大小做实时的文件校验方式! // 注意:通过比对文件大小做实时的文件校验方式!
string filePath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash); string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.Hash);
if (File.Exists(filePath)) if (File.Exists(filePath))
{ {
long fileSize = FileUtility.GetFileSize(filePath); long fileSize = FileUtility.GetFileSize(filePath);

View File

@ -1,55 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
[Serializable]
internal sealed class PatchCache
{
/// <summary>
/// 缓存的APP内置版本
/// </summary>
public string CacheAppVersion = string.Empty;
/// <summary>
/// 读取缓存文件
/// 注意:如果文件不存在则创建新的缓存文件
/// </summary>
public static PatchCache LoadCache()
{
if (SandboxHelper.CheckSandboxCacheFileExist())
{
string filePath = SandboxHelper.GetSandboxCacheFilePath();
string jsonData = FileUtility.ReadFile(filePath);
var patchCache = JsonUtility.FromJson<PatchCache>(jsonData);
YooLogger.Log($"Load cache file : {patchCache.CacheAppVersion}");
return patchCache;
}
else
{
YooLogger.Log($"Create cache file : {Application.version}");
PatchCache cache = new PatchCache();
cache.CacheAppVersion = Application.version;
string filePath = SandboxHelper.GetSandboxCacheFilePath();
string jsonData = JsonUtility.ToJson(cache);
FileUtility.CreateFile(filePath, jsonData);
return cache;
}
}
/// <summary>
/// 更新缓存文件
/// </summary>
public static void UpdateCache()
{
YooLogger.Log($"Update patch cache to disk : {Application.version}");
PatchCache cache = new PatchCache();
cache.CacheAppVersion = Application.version;
string filePath = SandboxHelper.GetSandboxCacheFilePath();
string jsonData = JsonUtility.ToJson(cache);
FileUtility.CreateFile(filePath, jsonData);
}
}
}

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace YooAsset namespace YooAsset
{ {
@ -69,6 +70,35 @@ namespace YooAsset
return LocalPatchManifest.ResourceVersion; return LocalPatchManifest.ResourceVersion;
} }
/// <summary>
/// 清空未被使用的缓存文件
/// </summary>
public void ClearUnusedCacheFiles()
{
string cacheFolderPath = SandboxHelper.GetCacheFolderPath();
if (Directory.Exists(cacheFolderPath) == false)
return;
DirectoryInfo directoryInfo = new DirectoryInfo(cacheFolderPath);
foreach (FileInfo fileInfo in directoryInfo.GetFiles())
{
bool used = false;
foreach (var patchBundle in LocalPatchManifest.BundleList)
{
if (fileInfo.Name == patchBundle.Hash)
{
used = true;
break;
}
}
if(used == false)
{
YooLogger.Log($"Delete unused cache file : {fileInfo.Name}");
File.Delete(fileInfo.FullName);
}
}
}
/// <summary> /// <summary>
/// 创建下载器 /// 创建下载器
/// </summary> /// </summary>

View File

@ -5,17 +5,17 @@ namespace YooAsset
{ {
internal static class LocationServicesHelper internal static class LocationServicesHelper
{ {
private static System.Type AssetBundleGrouperSettingHelperClassType; private static System.Type _classType;
public static void InitEditorPlayMode(bool enableAddressable) public static void InitEditorPlayMode(bool enableAddressable)
{ {
AssetBundleGrouperSettingHelperClassType = Assembly.Load("YooAsset.Editor").GetType("YooAsset.Editor.AssetBundleGrouperRuntimeSupport"); _classType = Assembly.Load("YooAsset.Editor").GetType("YooAsset.Editor.AssetBundleGrouperRuntimeSupport");
InvokePublicStaticMethod(AssetBundleGrouperSettingHelperClassType, "InitEditorPlayMode", enableAddressable); InvokePublicStaticMethod(_classType, "InitEditorPlayMode", enableAddressable);
} }
public static string ConvertLocationToAssetPath(string location) public static string ConvertLocationToAssetPath(string location)
{ {
return (string)InvokePublicStaticMethod(AssetBundleGrouperSettingHelperClassType, "ConvertLocationToAssetPath", location); return (string)InvokePublicStaticMethod(_classType, "ConvertLocationToAssetPath", location);
} }
private static object InvokePublicStaticMethod(System.Type type, string method, params object[] parameters) private static object InvokePublicStaticMethod(System.Type type, string method, params object[] parameters)
{ {
var methodInfo = type.GetMethod(method, BindingFlags.Public | BindingFlags.Static); var methodInfo = type.GetMethod(method, BindingFlags.Public | BindingFlags.Static);

View File

@ -80,63 +80,42 @@ namespace YooAsset
/// </summary> /// </summary>
internal static class SandboxHelper internal static class SandboxHelper
{ {
private const string StrCacheFileName = "Cache.bytes"; private const string CacheFolderName = "CacheFiles";
private const string StrCacheFolderName = "CacheFiles";
/// <summary> /// <summary>
/// 清空沙盒目录 /// 删除沙盒总目录
/// </summary> /// </summary>
public static void ClearSandbox() public static void DeleteSandbox()
{ {
string directoryPath = PathHelper.MakePersistentLoadPath(string.Empty); string directoryPath = PathHelper.MakePersistentLoadPath(string.Empty);
if (Directory.Exists(directoryPath)) if (Directory.Exists(directoryPath))
Directory.Delete(directoryPath, true); Directory.Delete(directoryPath, true);
} }
/// <summary>
/// 删除沙盒内的缓存文件
/// </summary>
public static void DeleteSandboxCacheFile()
{
string filePath = GetSandboxCacheFilePath();
if (File.Exists(filePath))
File.Delete(filePath);
}
/// <summary> /// <summary>
/// 删除沙盒内的缓存文件夹 /// 删除沙盒内的缓存文件夹
/// </summary> /// </summary>
public static void DeleteSandboxCacheFolder() public static void DeleteCacheFolder()
{ {
string directoryPath = PathHelper.MakePersistentLoadPath(StrCacheFolderName); string directoryPath = GetCacheFolderPath();
if (Directory.Exists(directoryPath)) if (Directory.Exists(directoryPath))
Directory.Delete(directoryPath, true); Directory.Delete(directoryPath, true);
} }
/// <summary> /// <summary>
/// 获取沙盒内缓存文件的路径 /// 获取缓存文件夹路径
/// </summary> /// </summary>
public static string GetSandboxCacheFilePath() public static string GetCacheFolderPath()
{ {
return PathHelper.MakePersistentLoadPath(StrCacheFileName); return PathHelper.MakePersistentLoadPath(CacheFolderName);
}
/// <summary>
/// 检测沙盒内缓存文件是否存在
/// </summary>
public static bool CheckSandboxCacheFileExist()
{
string filePath = GetSandboxCacheFilePath();
return File.Exists(filePath);
} }
/// <summary> /// <summary>
/// 获取缓存文件的存储路径 /// 获取缓存文件的存储路径
/// </summary> /// </summary>
public static string MakeSandboxCacheFilePath(string fileName) public static string MakeCacheFilePath(string fileName)
{ {
return PathHelper.MakePersistentLoadPath($"{StrCacheFolderName}/{fileName}"); return PathHelper.MakePersistentLoadPath($"{CacheFolderName}/{fileName}");
} }
} }
@ -155,7 +134,7 @@ namespace YooAsset
foreach (var patchBundle in appPatchManifest.BundleList) foreach (var patchBundle in appPatchManifest.BundleList)
{ {
// 如果已经在沙盒内 // 如果已经在沙盒内
string filePath = SandboxHelper.MakeSandboxCacheFilePath(patchBundle.Hash); string filePath = SandboxHelper.MakeCacheFilePath(patchBundle.Hash);
if (System.IO.File.Exists(filePath)) if (System.IO.File.Exists(filePath))
continue; continue;

View File

@ -675,22 +675,37 @@ namespace YooAsset
#region 沙盒相关 #region 沙盒相关
/// <summary> /// <summary>
/// 清空沙盒目录 /// 获取沙盒的根路径
/// 注意:可以使用该方法修复我们本地的客户端
/// </summary>
public static void ClearSandbox()
{
YooLogger.Warning("Clear sandbox.");
SandboxHelper.ClearSandbox();
}
/// <summary>
/// 获取沙盒文件夹的路径
/// </summary> /// </summary>
public static string GetSandboxRoot() public static string GetSandboxRoot()
{ {
return PathHelper.MakePersistentRootPath(); return PathHelper.MakePersistentRootPath();
} }
/// <summary>
/// 清空沙盒目录
/// </summary>
public static void ClearSandbox()
{
SandboxHelper.DeleteSandbox();
}
/// <summary>
/// 清空所有的缓存文件
/// </summary>
public static void ClearAllCacheFiles()
{
SandboxHelper.DeleteCacheFolder();
}
/// <summary>
/// 清空未被使用的缓存文件
/// </summary>
public static void ClearUnusedCacheFiles()
{
if (_playMode == EPlayMode.HostPlayMode)
_hostPlayModeImpl.ClearUnusedCacheFiles();
}
#endregion #endregion
#region 内部方法 #region 内部方法