序列化 反序列化

shuli198869 2010-12-30 10:57:40
我需要序列化、反序列化一份数据,数据量很大,用什么方法速度会快一些(序列化出来的二进制大约80M),我现在做的序列化要13秒,反序列化要2分40秒
...全文
799 56 打赏 收藏 转发到动态 举报
写回复
用AI写文章
56 条回复
切换为时间正序
请发表友善的回复…
发表回复
dclian 2011-06-23
  • 打赏
  • 举报
回复
序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。
.NET框架提供了两种串行化的方式:1、是使用BinaryFormatter进行串行化;2、使用SoapFormatter进行串行化;3、使用XmlSerializer进行串行化。第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储;第三种其实和第二种差不多也是XML的格式存储,只不过比第二种的XML格式要简化很多(去掉了SOAP特有的额外信息)。
可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、2可以使用[NonSerialized]属性来标志,2、可以使用[XmlIgnore]来标志。


3、使用XmlSerializer进行串行化
关于格式化器还有一个问题,假设我们需要XML,但是不想要SOAP特有

的额外信息,那么我们应该怎么办呢?有两中方案:要么编写一个实现

IFormatter接口的类,采用的方式类似于SoapFormatter类,但是没有你不需

要的信息;要么使用库类XmlSerializer,这个类不使用Serializable属性

,但是它提供了类似的功能。
如果我们不想使用主流的串行化机制,而想使用XmlSeralizer进行串行

化我们需要做一下修改:
a.添加System.Xml.Serialization命名空间。
b.Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性

,它的行为与NoSerialized类似。
c.XmlSeralizer要求类有个默认的构造器,这个条件可能已经满足了。
下面看示例:
要序列化的类:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Serialization;
[Serializable]
public class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}


public string Sex;
public int Age = 31;
public Course[] Courses;

public Person()
{
}
public Person(string Name)
{
name = Name;
Sex = "男";
}
}
[Serializable]
public class Course
{
public string Name;
[XmlIgnore]
public string Description;
public Course()
{
}
public Course(string name, string description)
{
Name = name;
Description = description;
}
}
序列化和反序列化方法:



public void XMLSerialize()
{
Person c = new Person("cyj");
c.Courses = new Course[2];
c.Courses[0] = new Course("英语", "交流工具");
c.Courses[1] = new Course("数学","自然科学");
XmlSerializer xs = new XmlSerializer(typeof(Person));
Stream stream = new FileStream

("c:\\cyj.XML",FileMode.Create,FileAccess.Write,FileShare.Read);
xs.Serialize(stream,c);
stream.Close();
}
public void XMLDeserialize()
{
XmlSerializer xs = new XmlSerializer(typeof(Person));
Stream stream = new FileStream

("C:\\cyj.XML",FileMode.Open,FileAccess.Read,FileShare.Read);
Person p = xs.Deserialize(stream) as Person;
Response.Write(p.Name);
Response.Write(p.Age.ToString());
Response.Write(p.Courses[0].Name);
Response.Write(p.Courses[0].Description);
Response.Write(p.Courses[1].Name);
Response.Write(p.Courses[1].Description);
stream.Close();
}

这里Course类的Description属性值将始终为null,生成的xml文档中也没有

该节点。

4、自定义序列化
如果你希望让用户对类进行串行化,但是对数据流的组织方式不完全满

意,那么可以通过在自定义类中实现接口来自定义串行化行为。这个接口只

有一个方法,GetObjectData. 这个方法用于将对类对象进行串行化所需要

的数据填进SerializationInfo对象。你使用的格式化器将构造

SerializationInfo对象,然后在串行化时调用GetObjectData. 如果类的父

类也实现了ISerializable,那么应该调用GetObjectData的父类实现。
如果你实现了ISerializable,那么还必须提供一个具有特定原型的构

造器,这个构造器的参数列表必须与GetObjectData相同。这个构造器应该

被声明为私有的或受保护的,以防止粗心的开发人员直接使用它。
示例如下:
实现ISerializable的类:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
/**//// <summary>
/// Employee 的摘要说明
/// </summary>
[Serializable]
public class Employee:ISerializable
{
public int EmpId=100;
public string EmpName="刘德华";
[NonSerialized]
public string NoSerialString = "NoSerialString-Test";
public Employee()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
private Employee(SerializationInfo info, StreamingContext

ctxt)
{
EmpId = (int)info.GetValue("EmployeeId", typeof(int));
EmpName = (String)info.GetValue("EmployeeName",typeof

(string));
//NoSerialString = (String)info.GetValue

("EmployeeString",typeof(string));
}
public void GetObjectData(SerializationInfo info,

StreamingContext ctxt)
{
info.AddValue("EmployeeId", EmpId);
info.AddValue("EmployeeName", EmpName);
//info.AddValue("EmployeeString", NoSerialString);
}
}

序列化和反序列化方法:
public void OtherEmployeeClassTest()
{
Employee mp = new Employee();
mp.EmpId = 10;
mp.EmpName = "邱枫";
mp.NoSerialString = "你好呀";
Stream steam = File.Open("c:\\temp3.dat",

FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
Response.Write("Writing Employee Info:");
bf.Serialize(steam,mp);
steam.Close();
mp = null;
//反序列化
Stream steam2 = File.Open("c:\\temp3.dat", FileMode.Open);
BinaryFormatter bf2 = new BinaryFormatter();
Response.Write("Reading Employee Info:");
Employee mp2 = (Employee)bf2.Deserialize(steam2);
steam2.Close();
Response.Write(mp2.EmpId);
Response.Write(mp2.EmpName);
Response.Write(mp2.NoSerialString);
}




shuli198869 2011-02-11
  • 打赏
  • 举报
回复
[Quote=引用 54 楼 sp1234 的回复:]
如果你认为设计上不可分,为什么会在乎2分钟呢?我们有个报表一次要计算4个小时,也很正常。

如果你认为设计没有问题,就当我没说好了。反正我又不为你的项目负责。我只是凭经验告诉你,如果要找问题,小伎俩已经没用了,找设计上的问题。
[/Quote]
嗯,谢谢
  • 打赏
  • 举报
回复
如果你认为设计上不可分,为什么会在乎2分钟呢?我们有个报表一次要计算4个小时,也很正常。

如果你认为设计没有问题,就当我没说好了。反正我又不为你的项目负责。我只是凭经验告诉你,如果要找问题,小伎俩已经没用了,找设计上的问题。
shuli198869 2011-02-01
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 sp1234 的回复:]
举个例子吧,如果需要盖房取土,不要一次搬一座山,而应该一车一车地搬。这看起来只是“大小”的问题,其实是设计上“懒惰”的问题,不愿意去处理细节就是“懒惰”。
[/Quote]
我的数据是整体的、对象之间彼此有关系的,这样也可以分开处理吗?麻烦你稍稍讲详细点可以吗?
wy811007 2011-01-30
  • 打赏
  • 举报
回复
过来学习..好像这个就是哪个类似加密一样的把 把东西变成乱码那个..
billsquall 2011-01-30
  • 打赏
  • 举报
回复
多线程的是不是要把200M的数据分开处理?不然怎么多线程?
billsquall 2011-01-30
  • 打赏
  • 举报
回复
楼上说话太虚幻了,让人摸不清头绪

最好给个例子,有代码有真相
  • 打赏
  • 举报
回复
举个例子吧,如果需要盖房取土,不要一次搬一座山,而应该一车一车地搬。这看起来只是“大小”的问题,其实是设计上“懒惰”的问题,不愿意去处理细节就是“懒惰”。
guyehanxinlei 2011-01-30
  • 打赏
  • 举报
回复
换种数据存储吧
shuli198869 2011-01-30
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 cdglynn 的回复:]
引用 41 楼 sp1234 的回复:
我想这是设计错误。


严重同意!
[/Quote]
设计错误时什么意思?
西门喷血 2011-01-27
  • 打赏
  • 举报
回复
能 不序列化的尽量不要序列化
减少数据
shuli198869 2011-01-27
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 sp1234 的回复:]
我想这是设计错误。
[/Quote]什么意思?不是很清楚
  • 打赏
  • 举报
回复
不妨问问自己,能不能修改设计。使得每一次做序列化时,其结果通常都小于32k。
  • 打赏
  • 举报
回复
我想这是设计错误。
shuli198869 2011-01-27
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 lizhibin11 的回复:]
得自定义序列化反序列化方法,自定义的同时加入多线程也是可以的
[/Quote]
没用过自定义序列化反序列化呢
Wude_S 2011-01-27
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 robbish 的回复:]
留个贴,俺不是专业出身,这个概念还没搞明白怎么回事呢!以后备查
[/Quote]留个贴,俺不是专业出身,这个概念还没搞明白怎么回事呢!以后备查
cdglynn 2011-01-27
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 sp1234 的回复:]
我想这是设计错误。
[/Quote]

严重同意!
robbish 2011-01-23
  • 打赏
  • 举报
回复
留个贴,俺不是专业出身,这个概念还没搞明白怎么回事呢!以后备查
lizhibin11 2011-01-22
  • 打赏
  • 举报
回复
得自定义序列化反序列化方法,自定义的同时加入多线程也是可以的
lixiaoyu928 2011-01-22
  • 打赏
  • 举报
回复
如果要快,那就自己写类的序列化和反序列化方法。不用.net的通用序列化方法Serialize。
加载更多回复(30)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧