138 lines
5.1 KiB
C#
138 lines
5.1 KiB
C#
|
|
using MainShell.Filewritable;
|
|||
|
|
using Newtonsoft.Json;
|
|||
|
|
using System;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
|
|||
|
|
namespace MXJM.FileWritable
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 通用的 JSON 可保存/加载基类,供任意需要持久化为 JSON 的类继承。
|
|||
|
|
/// 派生类可覆盖 Dir / FileName 指定保存位置与文件名。
|
|||
|
|
/// </summary>
|
|||
|
|
public abstract class JsonFileWritableBase
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 存储目录,派生类可覆盖。默认为应用程序基目录。
|
|||
|
|
/// 标记为 JsonIgnore 避免被序列化到文件中。
|
|||
|
|
/// </summary>
|
|||
|
|
[JsonIgnore]
|
|||
|
|
public virtual string Dir => Paths.RecipeBasePath;
|
|||
|
|
[JsonIgnore]
|
|||
|
|
public virtual IgnorePropertiesResolver IgnorePropertiesResolver =>new IgnorePropertiesResolver(new string[] { "PropertyChangedDispatcher" });
|
|||
|
|
/// <summary>
|
|||
|
|
/// 文件名,派生类可覆盖。
|
|||
|
|
/// </summary>
|
|||
|
|
[JsonIgnore]
|
|||
|
|
public virtual string FileName => $"{GetType().Name}.json";
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 将当前实例以 JSON 形式保存到 Dir/FileName。
|
|||
|
|
/// </summary>
|
|||
|
|
public void Write()
|
|||
|
|
{
|
|||
|
|
var dir = Dir ?? string.Empty;
|
|||
|
|
if (!Directory.Exists(dir))
|
|||
|
|
Directory.CreateDirectory(dir);
|
|||
|
|
|
|||
|
|
var path = Path.Combine(dir, FileName ?? "data.json");
|
|||
|
|
var settings = new JsonSerializerSettings
|
|||
|
|
{
|
|||
|
|
Formatting = Formatting.Indented,
|
|||
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
|||
|
|
ContractResolver = IgnorePropertiesResolver
|
|||
|
|
};
|
|||
|
|
var json = JsonConvert.SerializeObject(this, settings);
|
|||
|
|
File.WriteAllText(path, json);
|
|||
|
|
}
|
|||
|
|
public void Write(string path)
|
|||
|
|
{
|
|||
|
|
var dir = Path.GetDirectoryName(path);
|
|||
|
|
if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir))
|
|||
|
|
Directory.CreateDirectory(dir);
|
|||
|
|
var settings = new JsonSerializerSettings
|
|||
|
|
{
|
|||
|
|
Formatting = Formatting.Indented,
|
|||
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
|||
|
|
ContractResolver= IgnorePropertiesResolver
|
|||
|
|
};
|
|||
|
|
var json = JsonConvert.SerializeObject(this, settings);
|
|||
|
|
File.WriteAllText(path, json);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 异步保存的简单封装。
|
|||
|
|
/// </summary>
|
|||
|
|
public Task WriteAsync(CancellationToken cancellationToken = default)
|
|||
|
|
{
|
|||
|
|
return Task.Run(() =>
|
|||
|
|
{
|
|||
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|||
|
|
Write();
|
|||
|
|
}, cancellationToken);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从指定路径读取 JSON 并填充到当前实例(使用 PopulateObject,集合使用 Replace)。
|
|||
|
|
/// 如果需要返回一个全新的对象,请使用静态 LoadFromFile<T> 方法。
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="path">包含文件名的完整路径</param>
|
|||
|
|
public virtual void Read(string path)
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
|||
|
|
{
|
|||
|
|
Write();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var json = File.ReadAllText(path);
|
|||
|
|
var settings = new JsonSerializerSettings
|
|||
|
|
{
|
|||
|
|
ObjectCreationHandling = ObjectCreationHandling.Replace,
|
|||
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
|||
|
|
};
|
|||
|
|
JsonConvert.PopulateObject(json, this, settings);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从默认位置(Dir + FileName)读取。
|
|||
|
|
/// </summary>
|
|||
|
|
public virtual void Read()
|
|||
|
|
{
|
|||
|
|
var path = Path.Combine(Dir ?? string.Empty, FileName ?? string.Empty);
|
|||
|
|
Read(path);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 静态:从指定文件反序列化为新对象(若需要完整新实例,请使用此方法)。
|
|||
|
|
/// </summary>
|
|||
|
|
public static T LoadFromFile<T>(string path) where T : class
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
|||
|
|
return null;
|
|||
|
|
var json = File.ReadAllText(path);
|
|||
|
|
return JsonConvert.DeserializeObject<T>(json);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 静态:将任意对象保存到指定文件(路径自动创建)。
|
|||
|
|
/// </summary>
|
|||
|
|
public static void SaveToFile<T>(T obj, string path)
|
|||
|
|
{
|
|||
|
|
if (obj == null) throw new ArgumentNullException(nameof(obj));
|
|||
|
|
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path));
|
|||
|
|
|
|||
|
|
var dir = Path.GetDirectoryName(path);
|
|||
|
|
if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir))
|
|||
|
|
Directory.CreateDirectory(dir);
|
|||
|
|
|
|||
|
|
var settings = new JsonSerializerSettings
|
|||
|
|
{
|
|||
|
|
Formatting = Formatting.Indented,
|
|||
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
|||
|
|
};
|
|||
|
|
var json = JsonConvert.SerializeObject(obj, settings);
|
|||
|
|
File.WriteAllText(path, json);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|