当前位置: 首页 > news >正文

C#对象的本地保存与序列化详解笔记

一、对象本地保存的基本问题

对象在程序运行时存储在内存中,程序关闭后会被垃圾回收机制销毁,无法保留状态。若需在程序再次运行时恢复对象状态,需将对象信息持久化到磁盘(如文件)中。

原始保存方式的局限

直接将对象属性按顺序写入文本文件(如People.obj),通过顺序读取还原对象,存在明显缺点:

  • 强依赖顺序:存储与读取顺序必须完全一致,否则数据错乱;

  • 可读性差:无法直观区分文件中各字段对应对象的哪个属性;

  • 扩展性差:对象新增属性时,需修改存储和读取的全部逻辑。

二、序列化与反序列化

为解决原始保存方式的问题,引入 “序列化” 和 “反序列化” 机制:

  • 序列化:将对象状态转换为可存储(如文件)或可传输(如网络)的格式(二进制、XML、JSON 等)的过程。

  • 反序列化:将序列化后的格式(如二进制流、JSON 文本)还原为对象的过程。

三、三种常用序列化方式

1. 二进制序列化

将对象转换为二进制流,效率高、体积小,但可读性差(二进制无法直接看懂)。

核心组件
  • BinaryFormatter:位于System.Runtime.Serialization.Formatters.Binary命名空间,负责二进制序列化与反序列化。

使用步骤
  1. 标记类为可序列化:在类定义前添加[Serializable]特性(否则序列化失败);

  2. 创建文件流:通过FileStream指定存储路径和模式(如FileMode.Create创建文件);

  3. 实例化序列化器:创建BinaryFormatter对象;

  4. 执行序列化 / 反序列化:调用Serialize()(写入对象)或Deserialize()(读取对象);

  5. 释放资源:关闭文件流。

示例代码
// 1. 定义可序列化的类
[Serializable]  // 必须添加此特性
public class People
{public string Name { get; set; }public int Age { get; set; }public string Sex { get; set; }public string Birth { get; set; }
}
​
// 2. 序列化过程
public void BinarySerialize()
{People people = new People(){Name = "吴亦凡",Age = 18,Sex = "男",Birth = "2005-01-01"};
​// 创建文件流using (FileStream fs = new FileStream("people.bin", FileMode.Create)){BinaryFormatter bf = new BinaryFormatter();bf.Serialize(fs, people);  // 将对象写入流}
}
​
// 3. 反序列化过程
public void BinaryDeserialize()
{using (FileStream fs = new FileStream("people.bin", FileMode.Open)){BinaryFormatter bf = new BinaryFormatter();// 反序列化并转换为People类型People people = bf.Deserialize(fs) as People;Console.WriteLine($"姓名:{people.Name},年龄:{people.Age}");}
}
特点
  • 优点:效率高(二进制传输快)、体积小;

  • 缺点:不可读(无法直接查看文件内容)、仅限.NET 平台(跨平台兼容性差)。

2. JSON 序列化

JSON(JavaScript Object Notation)是一种轻量级文本格式,易读易写,跨平台兼容性强(支持多语言),是目前最常用的序列化格式之一。

JSON 格式示例:

{ "Name":"吴亦凡", "Age":18, "Sex":"男", "Birth":"2005-01-01" }
方式 1:原生DataContractJsonSerializer

依赖System.Runtime.Serialization.Json命名空间,需手动标记类和属性。

使用步骤
  1. 标记类和属性:类添加[DataContract],需序列化的属性添加[DataMember]

  2. 创建文件流:指定 JSON 文件路径;

  3. 实例化序列化器DataContractJsonSerializer需指定对象类型(如typeof(People));

  4. 序列化 / 反序列化:调用WriteObject()(序列化)或ReadObject()(反序列化)。

示例代码
// 1. 定义数据契约类
using System.Runtime.Serialization;
​
[DataContract]  // 标记为数据契约类
public class People
{[DataMember]  // 标记为需序列化的成员public string Name { get; set; }[DataMember]public int Age { get; set; }[DataMember]public string Sex { get; set; }[DataMember]public string Birth { get; set; }
}
​
// 2. 序列化
public void JsonSerialize_Native()
{People people = new People(){Name = "吴亦凡",Age = 18,Sex = "男",Birth = "2005-01-01"};
​using (FileStream fs = new FileStream("people.json", FileMode.Create)){DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(People));jsonSerializer.WriteObject(fs, people);  // 写入JSON}
}
​
// 3. 反序列化
public void JsonDeserialize_Native()
{using (FileStream fs = new FileStream("people.json", FileMode.Open)){DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(People));People people = jsonSerializer.ReadObject(fs) as People;  // 读取JSON并转换为对象Console.WriteLine($"姓名:{people.Name},年龄:{people.Age}");}
}
方式 2:第三方Newtonsoft.Json(推荐)

最流行的 JSON 处理库,简化序列化逻辑,无需标记特性,支持复杂对象和集合。

使用步骤
  1. 安装库:项目右键→“管理 NuGet 程序包”→搜索 “Newtonsoft.Json”→安装;

  2. 引入命名空间using Newtonsoft.Json;

  3. 序列化:调用JsonConvert.SerializeObject(对象)生成 JSON 字符串,写入文件;

  4. 反序列化:读取 JSON 字符串,调用JsonConvert.DeserializeObject<类型>(字符串)还原对象。

示例代码
using Newtonsoft.Json;
​
// 1. 定义普通类(无需任何特性)
public class People
{public string Name { get; set; }public int Age { get; set; }public string Sex { get; set; }public string Birth { get; set; }
}
​
// 2. 序列化
public void JsonSerialize_Newtonsoft()
{People people = new People(){Name = "吴亦凡",Age = 18,Sex = "男",Birth = "2005-01-01"};
​// 转换对象为JSON字符串string jsonStr = JsonConvert.SerializeObject(people);// 写入文件File.WriteAllText("people.json", jsonStr);
}
​
// 3. 反序列化
public void JsonDeserialize_Newtonsoft()
{// 读取JSON字符串string jsonStr = File.ReadAllText("people.json");// 转换为对象People people = JsonConvert.DeserializeObject<People>(jsonStr);Console.WriteLine($"姓名:{people.Name},年龄:{people.Age}");
}
JSON 序列化特点
  • 优点:文本格式易读、跨平台(支持 Java、Python 等多语言)、第三方库使用简单;

  • 缺点:相比二进制序列化,体积稍大、效率略低(但日常开发可忽略)。

四、三种序列化方式对比

序列化方式核心工具类可读性跨平台性易用性适用场景
二进制序列化BinaryFormatter差(二进制)差(仅限.NET)中(需标记特性)本地高效存储、.NET 内部通信
JSON 原生序列化DataContractJsonSerializer好(文本)中(需标记特性)简单跨平台数据交换
JSON 第三方序列化Newtonsoft.Json好(文本)优(无需标记)多数场景(推荐),如接口通信、配置存储

总结

  • 原始文本保存因依赖顺序,仅适用于极简单场景;

  • 二进制序列化适合.NET 内部高效存储,不追求可读性时使用;

  • JSON 序列化(尤其是Newtonsoft.Json)因易读、跨平台、易用,成为多数开发场景的首选。

http://www.lryc.cn/news/623840.html

相关文章:

  • GitLab CI/CD、Jenkins与GitHub Actions在Kubernetes环境中的方案对比分析
  • 【Golang】:错误处理
  • 任务型Agent架构简介
  • Visual Studio Code 基础设置指南
  • 【R语言】R 语言中打印含有双引号的字符串时会出现 “\” 的原因解析
  • GaussDB常用术语缩写及释义
  • 路由器配置之模式
  • 4.Ansible自动化之-部署文件到主机
  • nodejs 中间件
  • gitee 流水线+docker-compose部署 nodejs服务+mysql+redis
  • 【计算机网络面试】TCP/IP网络模型有哪几层
  • Matlab数字信号处理——基于最小均方误差(MMSE)估计的自适应脉冲压缩算法复现
  • ThinkPHP8学习篇(三):控制器
  • 7.Ansible自动化之-实施任务控制
  • 最优化:建模、算法与理论|02 Optimization Modeling and Typical Examples(1)
  • [优选算法专题二滑动窗口——将x减到0的最小操作数]
  • 【adb端口5555】烽火hg680-gy_烽火hg680-gc安卓9线刷烧录包 解决用一段时间就提示升级的问题
  • Shell脚本-for循环语法结构
  • 【前端基础】19、CSS的flex布局
  • 蓝凌EKP产品:JSP 性能优化和 JSTL/EL要点检查列表
  • rt-thread audio框架移植stm32 adc+dac,用wavplayer录音和播放
  • 【从零开始学习Redis】项目实战-黑马点评D2
  • scikit-learn/sklearn学习|多任务套索回归MultiTaskLasso解读
  • Windows_Server软件定义网络架构
  • 【Linux系列】如何在 Linux 服务器上快速获取公网
  • 每日两道算法题:DAY3
  • uniappx 安卓端本地打包的一些总结
  • 【位运算】查询子数组最大异或值|2693
  • CNV检测--单细胞空间vs基因组WGS/WES
  • AutoSar BSW介绍