首页 > 编程语言 >C#--序列化和反序列化

C#--序列化和反序列化

时间:2022-11-29 20:39:34浏览次数:43  
标签:ConfigList C# List -- new using 序列化 public


序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存、数据库或文件的过程。 它的主要用途是保存对象的状态,以便能够在需要时重新创建对象。 反向过程称为“反序列化”。

序列化的工作原理

下图展示了序列化的整个过程。

C#--序列化和反序列化_序列化


对象序列化

若要序列化对象,需要具有要序列化的对象、包含已序列化对象的一个流,以及一个 Formatter。

将 SerializableAttribute 特性应用于某个类型,以指示此类型的实例可以被序列化,具体做法在类之前加[Serializable]。

如果想让类中的某个字段不可序列化,请应用 NonSerializedAttribute 特性,具体做法在字段之前加[NonSerialized]。

C#代码实现:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace NetFrame
{
public class SerializeUtil
{
/// <summary>
/// 对象序列化
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] Encode(object value)
{
//创建编码解码的内存流对象
MemoryStream ms = new MemoryStream();
//二进制流序列化对象
BinaryFormatter bw = new BinaryFormatter();
//将obj对象序列化成二进制数据 写入到 内存流
bw.Serialize(ms, value);
byte[] result = new byte[ms.Length];
//将流数据 拷贝到结果数组
Buffer.BlockCopy(ms.GetBuffer(), 0, result, 0, (int)ms.Length);
ms.Close();
return result;
}

/// <summary>
/// 反序列化对象
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static object Decode(byte[] value)
{
//创建编码解码的内存流对象 并将需要反序列化的数据写入其中
MemoryStream ms = new MemoryStream(value);
//二进制流序列化对象
BinaryFormatter bw = new BinaryFormatter();
//将流数据反序列化为obj对象
object result = bw.Deserialize(ms);
ms.Close();
return result;
}
}
}


二进制和 XML 序列化

二进制序列化使用二进制编码来生成精简的序列化以供使用,如基于存储或套接字的网络流。

XML 序列化将对象的公共字段和属性或方法的参数和返回值序列化成符合特定 XML 架构定义语言 (XSD) 文档要求的 XML 流。

首先写一个需要序列化的类:

[Serializable]
public class ConfigMD5Data
{
public string fileName;
public string excelMD5;
public List<string> binaryMD5List;
public List<string> classNameList;
public List<string> typeNameList;
[NonSerialized]
public bool md5Changed;
[NonSerialized]
public bool classNameChanged;
[NonSerialized]
public bool binaryChanged;
}

[Serializable]
public class ConfigMD5
{
public List<ConfigMD5Data> m_ConfigMD5List = new List<ConfigMD5Data>();
}


二进制序列化的C#实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace StructScript
{
class BinaryFormatterTest
{
private static string m_ConfigMD5Path1;
private static ConfigMD5 m_ConfigList;

private static void Main(string[] args)
{
m_ConfigMD5Path1 = "config.bytes";
m_ConfigList = new ConfigMD5();
for (int i = 0; i < 5; i++)
{
ConfigMD5Data data = new ConfigMD5Data();
data.fileName = "test" + i;
m_ConfigList.m_ConfigMD5List.Add(data);
}
Serialize();
Deserialize();
Console.ReadLine();
}

private static void Serialize()
{
FileStream fs = new FileStream(m_ConfigMD5Path1, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fs, m_ConfigList);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
}
finally
{
fs.Close();
}
}

private static void Deserialize()
{
if (File.Exists(m_ConfigMD5Path1))
{
FileStream fs = new FileStream(m_ConfigMD5Path1, FileMode.Open);
try
{
BinaryFormatter formatter = new BinaryFormatter();
m_ConfigList = formatter.Deserialize(fs) as ConfigMD5;
int count = m_ConfigList.m_ConfigMD5List.Count;
for (int i = 0; i < count; i++)
{
ConfigMD5Data data = m_ConfigList.m_ConfigMD5List[i];
Console.WriteLine(data.fileName);
}
}
catch (SerializationException e)
{
Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
}
finally
{
fs.Close();
}
}
}

[Serializable]
public class ConfigMD5Data
{
public string fileName;
public string excelMD5;
public List<string> binaryMD5List;
public List<string> classNameList;
public List<string> typeNameList;
[NonSerialized]
public bool md5Changed;
[NonSerialized]
public bool classNameChanged;
[NonSerialized]
public bool binaryChanged;
}

[Serializable]
public class ConfigMD5
{
public List<ConfigMD5Data> m_ConfigMD5List = new List<ConfigMD5Data>();
}
}
}


输出结果:

C#--序列化和反序列化_序列化_02

Xml序列化C#实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;

namespace StructScript
{
public class XmlFormatterTest
{
private static string m_ConfigMD5Path;
private static ConfigMD5 m_ConfigList;

private static void Main(string[] args)
{
m_ConfigMD5Path = "config.xml";
m_ConfigList = new ConfigMD5();
for (int i = 0; i < 5; i++)
{
ConfigMD5Data data = new ConfigMD5Data();
data.fileName = "test" + i;
m_ConfigList.m_ConfigMD5List.Add(data);
}
SaveXml();
LoadXml();
Console.ReadLine();
}

public static bool SaveXml()
{
DeleteFile(m_ConfigMD5Path);
using (StreamWriter sw = new StreamWriter(m_ConfigMD5Path, false, Encoding.UTF8))
{
XmlSerializer serializer = new XmlSerializer(typeof(ConfigMD5));
try
{
serializer.Serialize(sw, m_ConfigList);
}
catch (Exception e)
{
Console.WriteLine("Load ConfigMD5 fail, error: " + e.Message);
}
}
return true;
}

public static bool DeleteFile(string filePath)
{
if (File.Exists(filePath))
{
File.Delete(filePath);
return true;
}
return false;
}

public static void LoadXml()
{
if (File.Exists(m_ConfigMD5Path))
{
try
{
using (StreamReader sr = new StreamReader(m_ConfigMD5Path, Encoding.UTF8))
{
XmlSerializer serializer = new XmlSerializer(typeof(ConfigMD5));
m_ConfigList = serializer.Deserialize(sr) as ConfigMD5;
int count = m_ConfigList.m_ConfigMD5List.Count;
for (int i = 0; i < count; i++)
{
ConfigMD5Data data = m_ConfigList.m_ConfigMD5List[i];
Console.WriteLine(data.fileName);
}
}
}
catch (Exception e)
{
Console.WriteLine("Load ConfigMD5 fail, error: " + e.Message);
}
}
}

[Serializable]
public class ConfigMD5Data
{
public string fileName;
public string excelMD5;
public List<string> binaryMD5List;
public List<string> classNameList;
public List<string> typeNameList;
[NonSerialized]
public bool md5Changed;
[NonSerialized]
public bool classNameChanged;
[NonSerialized]
public bool binaryChanged;
}

[Serializable]
public class ConfigMD5
{
public List<ConfigMD5Data> m_ConfigMD5List = new List<ConfigMD5Data>();
}
}
}

输出结果:

C#--序列化和反序列化_序列化_02

总结:

在二进制序列化中,所有成员(包括只读成员)都会被序列化,且性能也会有所提升。 XML 序列化可提高代码可读性,以及对象共享和使用的灵活性,从而实现互操作性。


标签:ConfigList,C#,List,--,new,using,序列化,public
From: https://blog.51cto.com/u_6871414/5896965

相关文章

  • C#--泛型委托Action<T>、Func<T>、Predicate<T>的解析和用法
    C#中的委托(Delegate)类似于C或C++中函数的指针。委托是保存对某个方法引用的一种引用类型变量。若要引用的方法,具有两个参数没有返回值,使用Action<T1, T2>委托,则不需要......
  • Unity Animator -- Apply Root Motion
    Animator.ApplyRootMotion这个属性是用来控制物体在播放骨骼动画的时候是否应用骨骼根节点的运动参数。一、当没有骨骼根节点的情况时,比如只是一个Cube立方体,如果勾选了Appl......
  • 【详细解析版】Unity UGUI Mask组件实现原理
    MaskingisimplementedusingthestencilbufferoftheGPU.即Mask是利用了GPU的模板缓冲来实现的,关于模板,打个简单的比方,就像一个面具,可以挡住一部分“脸”的显示一样。......
  • Unity-利用SkinnedMeshRenderer和Mesh的BindPose实现骨骼动画
    SkinnedMeshRenderer蒙皮网格渲染器。蒙皮是指将Mesh中的顶点附着(绑定)在骨骼之上,而且每个顶点可以被多个骨骼所控制。骨骼是皮肤网格内的不可见对象,它们影响动画过程中网格......
  • Unity判断对象是否在视野内
    判断对象是否在视野内,有两种方式:第一种:不设置固定的目标,使用LayerMask,设置寻找对象的Layer,使用Physics.OverlapSphere方法,以给定的位置为圆心,按照设定距离投射一个球体,返回......
  • Unity--Physics.OverlapSphere的参数LayerMask和GameObject的layer
    Layer介绍:Unity中是用int32来表示32个Layer层。int32表示二进制一共有32位(0—31)在Unity中每个GameObject都有Layer属性,默认的Layer都是Default。在Unity中可编辑的Layer共......
  • C#数据结构--Dictionary、HashTable、List、HashSet区别
    在.Net  模仿java的过程中,抛弃了HashMap,所以我们今天分析下Dictionary、HashTable、HashSet区别。处理碰撞,即碰撞到同一个Bucket槽上:Hashtable和Dictionary从数据结构上......
  • C#设计模式读书笔记之设计模式的设计原则
    设计模式的设计原则:(重要性从上往下排列)开闭原则:对扩展开放,对修改关闭依赖倒转原则:高层模块不应该依赖底层模块,它们都应该依赖抽象;要针对抽象层编程,而不要针对具体类编程。......
  • lua获取数组的长度
    获取数组的长度对于一个数组我们通常可以使用#来获取其长度tabletest={1,2,3,5,7}print(#tabletest)------》5使用这两种方法都能得到这个数组的长度,但是如果tabletest=......
  • 基于FPGA的正弦PWM产生系统verilog实现
    目录一、理论基础二、案例背景三、部分FPGA仿真四、仿真结论分析五、参考文献一、理论基础根据如下公式,首先建立simulink仿真模型:   这里,主要需要设计cos模块......