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