using System.IO; using System.Text; namespace SHH.CameraDashboard { /// /// 本地文件存储服务 /// 职责: /// 1. 提供通用的、异步的对象序列化和反序列化功能。 /// 2. 将对象保存为 UTF-8 编码的 JSON 文件。 /// 3. 从 JSON 文件中读取并反序列化为对象。 /// 4. 处理文件不存在、内容为空或格式错误等常见异常情况。 /// public static class LocalStorageService { #region --- 保存方法 --- /// /// 将指定对象异步保存到文件。 /// /// 要保存的对象的类型。 /// 目标文件的完整路径。 /// 要保存的对象实例。 /// 当保存过程中发生任何错误时抛出。 public static async Task SaveAsync(string filePath, T data) { try { // 1. 确保文件所在的目录存在,如果不存在则创建 var directoryPath = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } // 2. 使用 JsonHelper 将对象序列化为 JSON 字符串 string json = JsonHelper.Serialize(data); // 3. 使用 StreamWriter 异步将 JSON 字符串写入文件 // - `false` 表示覆盖现有文件。 // - `Encoding.UTF8` 确保文件编码正确,特别是处理中文字符时。 using (var writer = new StreamWriter(filePath, false, Encoding.UTF8)) { await writer.WriteAsync(json); } } catch (Exception ex) { // 记录错误到调试输出 System.Diagnostics.Debug.WriteLine($"保存文件失败 [{filePath}]: {ex.Message}"); // 重新抛出异常,因为保存失败通常是一个需要上层处理的严重问题(例如,提示用户) throw; } } #endregion #region --- 加载方法 --- /// /// 从文件异步加载并反序列化为指定类型的对象。 /// /// 目标对象的类型。必须是引用类型且具有公共无参数构造函数。 /// 源文件的完整路径。 /// /// 成功时返回反序列化后的对象。 /// 如果文件不存在、内容为空、格式错误或发生任何异常,将返回一个新创建的默认对象实例。 /// public static async Task LoadAsync(string filePath) where T : class, new() { // 1. 如果文件不存在,直接返回一个新的默认对象 if (!File.Exists(filePath)) { return new T(); } try { // 2. 使用 StreamReader 异步读取文件全部内容 using (var reader = new StreamReader(filePath, Encoding.UTF8)) { string json = await reader.ReadToEndAsync(); // 3. 如果文件内容为空或只包含空白字符,返回一个新的默认对象 if (string.IsNullOrWhiteSpace(json)) { return new T(); } // 4. 使用 JsonHelper 尝试反序列化 JSON 字符串 var result = JsonHelper.Deserialize(json); // 5. 如果反序列化结果为 null (例如,JSON 内容为 "null" 或格式不匹配), // 则返回一个新的默认对象作为兜底。 return result ?? new T(); } } catch (Exception ex) { // 记录错误到调试输出 System.Diagnostics.Debug.WriteLine($"读取文件失败 [{filePath}]: {ex.Message}"); // 发生任何异常(如文件被占用、权限问题等),都返回一个新的默认对象, // 以确保程序能够继续运行而不会崩溃。 return new T(); } } #endregion } }