这里还要注意对象的序列化主要有两种用途:1) 在网络上传送对象的字节序列。2) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。
.net为我们主要提供了三种序列化方式:

它们的主要区别请参考下图:

最后来三段代码,简单实现常用的序列化和反序列化。
1、使用BinaryFormatter
using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace BinarySerialize
{
//要使一个类可序列化,最简单的方法是使用Serializable 属性对它进行标记
[Serializable]
public class User //要序列化的用户类
{
public int tid = 252;
public string name = "jeff wong";
[NonSerialized]
public string sex = "male"; // 性别被标识为不可序列化
}
public class SerializeUtil
{
private static string strFile = "c:\\User.data";
public static void Serialize(User testUser)
{
//可以用MemoryStream等
using (FileStream fs = new FileStream(strFile, FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, testUser);
}
}
public static User DeSerialize()
{
User testUser = null;
using (FileStream fs = new FileStream(strFile, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
testUser = (User)formatter.Deserialize(fs);
}
return testUser;
}
}
public class Program
{
static void Main()
{
SerializeUtil.Serialize(new User());//序列化
User tmpUser = SerializeUtil.DeSerialize();//反序列化
Console.WriteLine(tmpUser.tid + "-" + tmpUser.name);
Console.WriteLine(tmpUser.sex); //sex被标识为不可序列化,所以总为null
Console.ReadLine();
}
}
}
2、使用SoapFormatter
先添加System.Runtime.Serialization.Formatters.Soap引用,然后和BinaryFormatter类似,我们只需要做一下简单修改即可:
a.将using语句中的.Formatter.Binary改为.Formatter.Soap;
b.将所有的BinaryFormatter替换为SoapFormatter.
c.确保报存文件的扩展名为.xml
经过上面简单改动,即可实现SoapFormatter的串行化,这时候产生的文件就是一个xml格式的文件。

using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
namespace SoapSerialize
{
//要使一个类可序列化,最简单的方法是使用Serializable 属性对它进行标记
[Serializable]
public class User //要序列化的用户类
{
public int tid = 252;
public string name = "jeff wong";
[NonSerialized]
public string sex = "male"; // 性别被标识为不可序列化
}
public class SerializeUtil
{
private static string strFile = "c:\\User.xml"; //存为xml
public static void Serialize(User testUser)
{
using (FileStream fs = new FileStream(strFile, FileMode.Create))
{
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(fs, testUser);
}
}
public static User DeSerialize()
{
User testUser = null;
using (FileStream fs = new FileStream(strFile, FileMode.Open))
{
SoapFormatter formatter = new SoapFormatter();
testUser = (User)formatter.Deserialize(fs);
}
return testUser;
}
}
public class Program
{
static void Main()
{
SerializeUtil.Serialize(new User());//序列化
User tmpUser = SerializeUtil.DeSerialize();//反序列化
Console.WriteLine(tmpUser.tid + "-" + tmpUser.name);
Console.WriteLine(tmpUser.sex); //sex被标识为不可序列化,所以总为null
Console.ReadLine();
}
}
}
(3)、使用XmlSerializer
想使用XmlSeralizer进行串行化我们需要做一下修改:
a.添加System.Xml.Serialization命名空间.
b.Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的行为与NoSerialized类似.
c.XmlSeralizer要求类有个默认的构造器.

using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Xml.Serialization;
namespace XmllSerialize
{
[Serializable]
public class User //要序列化的用户类
{
public int tid = 252;
public string name;
[XmlIgnore]
public string sex = "male";
public User(string name)
{
this.name = name;
}
/// <summary>
/// 必须注意:XmlSeralizer要求类有个默认的构造器
/// </summary>
public User()
{
}
}
public class SerializeUtil
{
private static string strFile = "c:\\User.xml"; //存为xml
public static void Serialize(User testUser)
{
XmlSerializer xs = new XmlSerializer(typeof(User));
using (Stream stream = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.Read))
{
xs.Serialize(stream, testUser);
}
}
public static User DeSerialize()
{
User testUser = null;
using (FileStream fs = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
XmlSerializer xs = new XmlSerializer(typeof(User));
testUser = (User)xs.Deserialize(fs);
}
return testUser;
}
}
public class Program
{
static void Main()
{
SerializeUtil.Serialize(new User("jeff wong"));//序列化
User tmpUser = SerializeUtil.DeSerialize();//反序列化
Console.WriteLine(tmpUser.tid + "-" + tmpUser.name);
Console.WriteLine(tmpUser.sex);
Console.ReadLine();
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2007-07-02 今天做销售功能时在财务统计上遇到一个问题 想了一个解决方案