序列化和反序列化

后浪 2011-09-05 05:08:18
SiteConfig.xml

<?xml version="1.0" encoding="utf-8" ?>
<xmlroot>
<shoptemplate text="大众点评" myspace="dzdp" class="dzdp.CInfoCls">
<channel text="咖啡厅">search/category/4/30/g2027</channel>
<channel text="酒吧">search/category/4/30/g2029</channel>
<channel text="茶馆">search/category/4/30/g2025</channel>
<channel text="KTV">search/category/4/30/g4807</channel>
<channel text="电影院">search/category/4/30/g4782</channel>
<channel text="文化艺术">search/category/4/30/g4755</channel>
<channel text="景点/郊游">search/category/4/30/g4784</channel>
<channel text="公园">search/category/4/30/g4802</channel>
<channel text="足疗按摩">search/category/4/30/g4793</channel>
<channel text="桑拿水会">search/category/4/30/g4778</channel>
<channel text="游乐游艺">search/category/4/30/g4788</channel>
<channel text="桌面游戏">search/category/4/30/g6696</channel>
<channel text="桌球室">search/category/4/30/g24677</channel>
<channel text="DIY手工坊">search/category/4/30/g4762/g30g4762</channel>
</shoptemplate>
<newstemplate text="瑞丽女性网" myspace="rayli" class="rayli.CInfoCls">
<channel text="瑞丽夜店">zixun/LT_407604.html</channel>
<channel text="瑞丽酒吧">zixun/LT_379668.html</channel>
</newstemplate>
</xmlroot>

siteconfig.cs

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

namespace DME.Collector
{
/// <summary>
/// 配置文件SiteConfig.xml
/// </summary>
public static class SiteConfig
{
/// <summary>
/// 配置文件路径 路径"/SiteConfig.xml"
/// </summary>
private static string _FilePath = "\\SiteConfig.Config";
public static string FilePath { get { return _FilePath; } set { _FilePath = value; } }

/// <summary>
/// 根节点对象
/// </summary>
public static xmlroot xmlroot()
{
XmlSerializer xs = new XmlSerializer(typeof(xmlroot));
Stream stream;
string strpath = "SiteConfig.xml";
try
{

stream = new FileStream(strpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return (xmlroot)xs.Deserialize(stream);
}
catch
{
return FormatConfig();
}
}

public static xmlroot FormatConfig()
{
xmlroot RT = new xmlroot();
try
{
XmlSerializer xs = new XmlSerializer(typeof(xmlroot));
Stream stream = new FileStream("SiteConfig.xml", FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
xs.Serialize(stream, RT);
stream.Close();
return RT;
}
catch
{
return null;
}

}
}

/// <summary>
/// 序列化对象类,根节点root
/// </summary>
[XmlRoot("root")]
public class xmlroot
{
public List<template> shoptemplate;
public List<template> newstemplate;

}
/// <summary>
/// 序列化对象类,子节点 root》template
/// </summary>
[Serializable]
public class template {
private string _text;
[XmlAttribute("text")]
public string text { get { return _text; } set { _text = value; } }

private string _space;
[XmlAttribute("space")]
public string space { get { return _space; } set { _space = value; } }

private string _class;
[XmlAttribute("class")]
public string Class { get { return _class; } set { _class = value; } }


private List<channel> _channel;
[XmlElement(ElementName = "channel")]
public List<channel> channel { get { return _channel; } set { _channel = value; } }

}

/// <summary>
/// 序列化对象类,子节点 root》template》channel
/// </summary>
[Serializable]
public class channel {
private string _text;
[XmlAttribute("text")]
public string text { get { return _text; } set { _text = value; } }

}



}




我试过站点下可以获取到节点

现在我改成 winform下 就出现问题


try
{

stream = new FileStream(strpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return (xmlroot)xs.Deserialize(stream);
}
catch
{
return FormatConfig();
}


XML 文档(2, 2)中有错误。

序列得到
<?xml version="1.0"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
...全文
135 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
YnSky 2011-09-05
  • 打赏
  • 举报
回复
.Net 中的序列化与反序列化


一、概述
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象。
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。

二、对象的序列化主要有两种用途:
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁 盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基 本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。
2) 在网络上传送对象的字节序列。
对象仅在创建对象的应用程序域中有效。除非对象是从MarshalByRefObject派生得到或标记为 Serializable,否则,任何将对象作为参数传递或将其作为结果返回的尝试都将失败。如果对象标记为 Serializable,则该对象将被自动序列化,并从一个应用程序域传输至另一个应用程序域,然后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。此过程通常称为按值封送。如果对象是从MarshalByRefObject派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。也可以将从MarshalByRefObject派生得到的对象标记为Serializable。远程使用此对象时,负责进行序列化并已预先配置为SurrogateSelector的格式化程序将控制序列化过程,并用一个代理替换所有从MarshalByRefObject派生得到的对象。如果没有预先配置为SurrogateSelector,序列化体系结构将遵从下面的标准序列化规则.

三、.NET提供了三种序列化方式
[1]、XML Serializer
[2]、SOAP Serializer
[3]、BinarySerializer

四、基本序列化
要使一个类可序列化,最简单的方法是使用 Serializable 属性对它进行标记,如下所示:
[Serializable]
public class MyObject
{
public int n1 = 0;
public int n2 = 0;
public String str = null;
}
[BinarySerializer]
将此类的一个实例序列化为一个文件:
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "一些字符串";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();

反序列化:

IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open,
FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(fromStream);
stream.Close();

[XMLSerializer]
将此类的实例序列化成一个Xml文件.

XmlSerializer ser = new XmlSerializer(obj.GetType());
ser.Serialize(new FileStream(@"users.xml", FileMode.Create), obj);

反序列化:

XmlSerializer serializer = new XmlSerializer(Type.GetType("MyObject"));
MyObject my=(MyObject)serializer.Deserialize(new FileStream(@"users.xml",FileMode.Open));

说明:使用二进制格式化程序进行序列化。您只需创建一个要使用的流和格式化程序的实例,然后调用格式化程序的 Serialize 方法。流和要序列化的对象实例作为参数提供给此调用。类中的所有成员变量(甚至标记为 private 的变量)都将被序列化,但这一点在本例中未明确体现出来。在这一点上,二进制序列化不同于只序列化公共字段的 XML 序列化程序。将对象还原到它以前的状态也非常容易。首先,创建格式化程序和流以进行读取,然后让格式化程序对对象进行反序列化。
[SOAP Serializer]
如果要求具有可移植性,请使用 SoapFormatter。所要做的更改只是将以上代码中的BinaryFormatter换 SoapFormatter,而 Serialize 和 Deserialize 调用不变。

机器人 2011-09-05
  • 打赏
  • 举报
回复
其他没细看, [XmlRoot("root")] 你定义的root name 是"root",可xml里是 "xmlroot"

鸭梨山大帝 2011-09-05
  • 打赏
  • 举报
回复
WinForm,WebForm都是用的Base Class Libaray,不应出现框架不一样就表现形式不一样,毕竟不是UI.
后浪 2011-09-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 liuchaolin 的回复:]

路径对没有?web有Server.MapPath,winform没有
[/Quote]路径我改对了
md5e 2011-09-05
  • 打赏
  • 举报
回复
路径对没有?web有Server.MapPath,winform没有

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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