Files
FlowScope/Packages/com.flowscope.gamecore/Runtime/Save/FileSaveStorage.cs
2026-06-04 14:54:49 +08:00

94 lines
2.8 KiB
C#

using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace FlowScope.Save
{
public interface ISaveStorage
{
Task WriteAsync(string key, byte[] data, CancellationToken cancellationToken);
Task<byte[]> ReadAsync(string key, CancellationToken cancellationToken);
void Delete(string key);
bool Exists(string key);
}
public sealed class FileSaveStorage : ISaveStorage
{
private readonly string _rootDirectory;
public FileSaveStorage(string rootDirectory = null)
{
_rootDirectory = string.IsNullOrWhiteSpace(rootDirectory)
? Path.Combine(Application.persistentDataPath, "FlowScopeSaves")
: rootDirectory;
}
public async Task WriteAsync(string key, byte[] data, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (data == null)
{
throw new ArgumentNullException(nameof(data));
}
Directory.CreateDirectory(_rootDirectory);
var path = GetPath(key);
using var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true);
await stream.WriteAsync(data, 0, data.Length, cancellationToken);
}
public async Task<byte[]> ReadAsync(string key, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var path = GetPath(key);
if (!File.Exists(path))
{
return null;
}
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true);
var data = new byte[stream.Length];
var read = 0;
while (read < data.Length)
{
var count = await stream.ReadAsync(data, read, data.Length - read, cancellationToken);
if (count == 0)
{
break;
}
read += count;
}
return data;
}
public void Delete(string key)
{
var path = GetPath(key);
if (File.Exists(path))
{
File.Delete(path);
}
}
public bool Exists(string key)
{
return File.Exists(GetPath(key));
}
private string GetPath(string key)
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Save key is required.", nameof(key));
}
return Path.Combine(_rootDirectory, Convert.ToBase64String(Encoding.UTF8.GetBytes(key)) + ".json");
}
}
}