94 lines
2.8 KiB
C#
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");
|
|
}
|
|
}
|
|
}
|