BITKit/Packages/Runtime~/Core/Assets/BITAssets.cs

146 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using System.Text;
using System.IO.Compression;
using System.Threading.Tasks;
namespace BITKit.IO
{
public record BITHeader
{
// ReSharper disable once UnusedAutoPropertyAccessor.Global
public string Name { get; set; }
public DateTime CreateTime;
public DateTime LastModifiedTime;
// ReSharper disable once CollectionNeverQueried.Global
public readonly List<string> Files = new List<string>();
}
public class BITAssets : List<IAsset>
{
public static void Build(string path, params IAsset[] assets)
{
List<IAsset> assetList = new();
var header = new BITHeader
{
Name = path,
CreateTime = DateTime.Now,
LastModifiedTime = DateTime.Now
};
foreach (var asset in assets)
{
header.Files.Add(asset.Name);
}
assetList.Add(new BITAsset()
{
Name = "manifest.json",
Buffer = StringHelper.GetBytes(JsonConvert.SerializeObject(header, Formatting.Indented)),
});
assetList.AddRange(assets);
var file = new FileInfo(path);
if (file.Exists)
{
file.Delete();
}
using var zipFile = ZipFile.Open(path, ZipArchiveMode.Create);
foreach (var x in assetList)
{
var entry = zipFile.CreateEntry(x.Name);
using var ms = new MemoryStream(x.Buffer);
using var writer = entry.Open();
ms.CopyTo(writer);
}
zipFile.Dispose();
}
public static T ReadAs<T>(string path)
{
return Read<T>(path, typeof(T).Name);
}
public static T Read<T>(string path, string bufferPath, IStorageFile provider = null)
{
var json = ReadText(path, bufferPath, provider);
return Read<T>(json);
}
public static async Task<T> ReadAsync<T>(string path, string bufferPath, IStorageFile provider = null)
{
var json = await ReadTextAsync(path, bufferPath, provider);
return Read<T>(json);
}
// ReSharper disable once MemberCanBePrivate.Global
public static T Read<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
// ReSharper disable once MemberCanBePrivate.Global
public static async Task<IAsset> ReadAssetAsync(string path, string bufferPath, IStorageFile provider = null)
{
provider = provider ?? new FileProvider(path);
return ReadAsset(await provider.OpenReadAsync(), bufferPath);
}
// ReSharper disable once MemberCanBePrivate.Global
public static IAsset ReadAsset(string path, string bufferPath, IStorageFile provider = null)
{
provider = provider ?? new FileProvider(path);
return ReadAsset(provider.OpenRead(), bufferPath);
}
// ReSharper disable once MemberCanBePrivate.Global
public static IAsset ReadAsset(Stream stream, string bufferPath)
{
BITAsset asset = new()
{
Name = bufferPath
};
using var zip = new ZipArchive(stream, ZipArchiveMode.Read);
var entry = zip.GetEntry(bufferPath);
if (entry is null)
{
StringBuilder stringBuilder = new($"未找到{bufferPath}");
stringBuilder.AppendLine("已找到的Entry:");
foreach (var _entry in zip.Entries)
{
stringBuilder.AppendLine($"{_entry!.Name}\t{_entry!.FullName}");
}
throw new NullReferenceException(stringBuilder.ToString());
}
using var _stream = entry!.Open();
using var ms = new MemoryStream();
_stream.CopyTo(ms);
asset.Buffer = ms.ToArray();
return asset;
}
// ReSharper disable once MemberCanBePrivate.Global
public static string ReadText(string path, string bufferPath, IStorageFile provider = null)
{
var asset = ReadAsset(path, bufferPath, provider);
return StringHelper.GetString(asset.Buffer);
}
public static async Task<string> ReadTextAsync(string path, string bufferPath, IStorageFile provider = null)
{
var asset = await ReadAssetAsync(path, bufferPath, provider);
return StringHelper.GetString(asset.Buffer);
}
public void Build(string path)
{
Build(path, ToArray());
}
}
}