async UniTask <bool> ReadFileAsync(IAltoStorageData data) { string path = $"{ DataPath() }/{ SlotPrefix() }{ data.SaveFileName() }"; Log($"Read file : {path}"); if (!File.Exists(path)) { Log($"File not exists, so set initial data : { data.GetType() }"); data.OnCreateNewData(); return(false); } try { byte[] dataBytes; byte[] ivSeedBytes = new byte[IvSeedLength]; using (var fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read)) { dataBytes = new byte[fileStream.Length - IvSeedLength]; await fileStream.ReadAsync(ivSeedBytes, 0, IvSeedLength); await fileStream.ReadAsync(dataBytes, 0, dataBytes.Length); } string ivSeed = Encoding.UTF8.GetString(ivSeedBytes); dataBytes = AltoCrypto.Decrypt(dataBytes, CryptoKey(), ivSeed); string json = Encoding.UTF8.GetString(dataBytes); data.OnDeserialize(json); data.ClearDirty(); MigrateIfNeeded(data); return(true); } catch (Exception e) { Debug.LogException(e); return(false); } }
async UniTask <bool> WriteFileAsync(IAltoStorageData data, bool useDirtyCache = false) { try { string json = JsonUtility.ToJson(data); byte[] dataBytes = Encoding.UTF8.GetBytes(json); string ivSeed = IdUtil.GetGuidAs22Chars(); dataBytes = AltoCrypto.Encrypt(dataBytes, CryptoKey(), ivSeed); byte[] ivSeedBytes = Encoding.UTF8.GetBytes(ivSeed); string path = $"{ DataPath() }/{ SlotPrefix() }{ data.SaveFileName() }"; string tmpPath = path + ".tmp"; using (var fileStream = new FileStream(tmpPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { await fileStream.WriteAsync(ivSeedBytes, 0, ivSeedBytes.Length); await fileStream.WriteAsync(dataBytes, 0, dataBytes.Length); fileStream.Flush(flushToDisk: true); } if (File.Exists(path)) { File.Delete(path); } File.Move(tmpPath, path); data.ClearDirty(useDirtyCache); return(true); } catch (Exception e) { Debug.LogException(e); return(false); } }