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 Files = new List(); } public class BITAssets : List { public static void Build(string path, params IAsset[] assets) { List 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(string path) { return Read(path, typeof(T).Name); } public static T Read(string path, string bufferPath, IStorageFile provider = null) { var json = ReadText(path, bufferPath, provider); return Read(json); } public static async Task ReadAsync(string path, string bufferPath, IStorageFile provider = null) { var json = await ReadTextAsync(path, bufferPath, provider); return Read(json); } // ReSharper disable once MemberCanBePrivate.Global public static T Read(string json) { return JsonConvert.DeserializeObject(json); } // ReSharper disable once MemberCanBePrivate.Global public static async Task 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 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()); } } }