C#关于序列化和反序列化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#关于序列化和反序列化相关的知识,希望对你有一定的参考价值。
我将XML转为实例,报没有 Unicode 字节顺序标记。不能切换到 Unicode这个错,把XML文件内的这一行删掉就正常了,可是写入的时候是会自动生成这一行的,请问怎么解决
工具/原料Visual Studio(本文使用VS2013,其他版本亦可)。
准备工作和类设计
1
启动VS,新建C# 类库项目,并命名为KTools。
2
添加C# Winform项目,命名为Test,重命名主窗口为MainForm,并设置为启动项。同时在KTools项目添加文件夹Serializer,并在该文件夹中添加3个类:XMLSerializer、SoapSerializer和BinarySerializer,如下图:
3
该类库的设计目标是快速方便,最好把序列化和反序列化的方法做成静态方法,这样就可以省去了实例化的步骤。序列化大体上分为序列化到文件和序列化到流,虽然序列化到流更为通用,但序列化到流的步骤中似乎没有什么可简化的,故我们只讨论序列化到文件。对于序列化到文件,我们需要考虑文件是否存在、写入是否覆盖等,为了方便使用只考虑“存在覆盖”的原则。为了尽可能的避免异常(因为这样使用起来更简单,不必考虑是否会引发异常),我们必须确保对象可序列化、文件存在、反序列化时文件不空等。另外,为了避免反序列化时的类型转化,以及更好的使用类,把序列化和范序列化的方法做成泛型。
END
XML序列化和反序列化
1
XML序列化需要引用名称空间System.Xml.Serialization,序列化代码如下:
public static void Serialize<T>(T o, string filePath)
try
XmlSerializer formatter = new XmlSerializer(typeof(T));
StreamWriter sw = new StreamWriter(filePath, false);
formatter.Serialize(sw, o);
sw.Flush();
sw.Close();
catch (Exception)
2
XML反序列化,代码如下:
public static T DeSerialize<T>(string filePath)
try
XmlSerializer formatter = new XmlSerializer(typeof(T));
StreamReader sr = new StreamReader(filePath);
T o = (T)formatter.Deserialize(sr);
sr.Close();
return o;
catch (Exception)
return default(T);
END
Soap序列化
1
Soap序列化需要名称引用空间System.Runtime.Serialization.Formatters.Soap,并且该dll引用需要手工添加。Soap序列化代码,如下:
public static void Serialize<T>(T o, string filePath)
try
SoapFormatter formatter = new SoapFormatter();
// StreamWriter sw = new StreamWriter(filePath, false);
Stream stream = new FileStream(filePath , FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, o);
stream.Flush();
stream.Close();
catch (Exception)
2
Soap反序列化,代码如下:
public static T DeSerialize<T>(string filePath)
try
SoapFormatter formatter = new SoapFormatter();
// StreamReader sr = new StreamReader(filePath);
Stream destream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
T o = (T)formatter.Deserialize(destream);
destream.Flush();
destream.Close();
return o;
catch (Exception)
return default(T);
END
Binary序列化和反序列化
1
Binary序列化,代码:
public static void Serialize<T>(T o, string filePath)
try
BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, o);
stream.Flush();
stream.Close();
catch (Exception)
2
Binary反序列化,代码:
public static T DeSerialize<T>(string filePath)
try
BinaryFormatter formatter = new BinaryFormatter();
Stream destream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
T o = (T)formatter.Deserialize(destream);
destream.Flush();
destream.Close();
return o;
catch (Exception)
return default(T);
END
测试
在Test项目中的MainForm窗体中添加两个Button控件,分别命名为“序列化”和“反序列化”,并添加代码:
public partial class MainForm : Form
public MainForm()
InitializeComponent();
private void button1_Click(object sender, EventArgs e)
string str = "Hello world!!!";
KTools.Serializer.XMLSerializer.Serialize<string>(str, "1.txt");
MessageBox.Show("序列化完毕");
private void button2_Click(object sender, EventArgs e)
string str = KTools.Serializer.XMLSerializer.DeSerialize<string>("1.txt");
MessageBox.Show(str);
调试运行,查看结果: 参考技术A 用处就是以文本(二进制/XML)的形式保存/传递你对象的状态了,这样就可以在下次或者在别的地方(互联网上的另一个程序)读取这些文本(二进制/XML)以还原对象的状态。
C# JSON 反序列化
下面的JSON字符串要转为对象比较容易:
JSON字符串:"A":0,"B":1,"C":0,"D":3
[DataContract(Namespace = "XXX")]
public class MyClass
[DataMember(Order = 1)]
public int A get; set;
[DataMember(Order = 2)]
public int B get; set;
[DataMember(Order = 3)]
public int C get; set;
[DataMember(Order = 4)]
public int D get; set;
var ser = new DataContractJsonSerializer(typeof(MyClass));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(JSON字符串));
MyClass myClass1 = (MyClass)ser.ReadObject(ms);
运用以上代码即可成功转换.
问题是,像下边这样的JSON字符串该如何转换
JSON字符串:"112":0,"325":1,"109":4
这样是不可取的:
[DataContract(Namespace = "XXX")]
public class MyClass
[DataMember(Order = 1)]
public int 112 get; set;
[DataMember(Order = 2)]
public int 325 get; set;
[DataMember(Order = 3)]
public int 109 get; set;
因为C#中变量不能以数字开头,而且类似"112":0这样的项不是固定不变的,数量也不固定.试过用SortedList,但不能成功.请有经验的赐教一下.
不固定的意思是说:这一次是"112":0下一次可能就是"113":0或"234243":0等等,无法预知会来个什么.
数量不固定的意思是说:例子中只给出了3个,但也可能是3万个.
个人凭经验觉得这应该是一个字典类,因为字典类可以用任何字符串做KEY,可以容纳任意数量的项.
原来还有JavaScriptSerializer这东西
JavaScriptSerializer能支持SortedList<string, int>
所以问题很简单就解决了,谢谢.
能否再给我上一课,说一下DataContractJsonSerializer与JavaScriptSerializer有什么区别,在哪种情况下选择哪个比较合理,有在网上搜了一下,都是英文的,看不大懂...
---------------------------
感谢【depluin】的解答:
……
DataContractJsonSerializer 可以处理其中的键类型不是字符串的词典,而 JavascriptSerializer 则无法处理,在这一方面前者的功能更为强大。但后者与 JSON 的兼容性更好。
====================================
可惜百度知道没有分配分数的功能,只能将分数给与其中一个,再次感谢两位的帮助!
在下面的列表中:此字典用 JSON 对象表示:
DataContractJsonSerializer 将其表示为 ["Key":"one","Value":1,"Key":"two","Value":2]
JavascriptSerializer 将其表示为 “one”:1,”two”:2
DataContractJsonSerializer 可以处理其中的键类型不是字符串的词典,而 JavascriptSerializer 则无法处理,在这一方面前者的功能更为强大。但后者与 JSON 的兼容性更好。 参考技术B 不要用DataContract
var serialize = new JavaScriptSerializer();
var obj= serialize.Deserialize<MyClass>(str);
可以"112":0,"325":1,"109":4
str.Replace(",",",");
"["+str+"]"
将Json对象转为HashTable再进行后序列化本回答被提问者采纳
以上是关于C#关于序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章