惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
S
Schneier on Security
aimingoo的专栏
aimingoo的专栏
T
Troy Hunt's Blog
U
Unit 42
Hacker News - Newest:
Hacker News - Newest: "LLM"
V2EX - 技术
V2EX - 技术
T
The Blog of Author Tim Ferriss
V
Visual Studio Blog
H
Heimdal Security Blog
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Cloudbric
Cloudbric
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
The Cloudflare Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
MyScale Blog
MyScale Blog
F
Fortinet All Blogs
N
News | PayPal Newsroom
Attack and Defense Labs
Attack and Defense Labs
D
DataBreaches.Net
N
News and Events Feed by Topic
Security Archives - TechRepublic
Security Archives - TechRepublic
Forbes - Security
Forbes - Security
Simon Willison's Weblog
Simon Willison's Weblog
F
Full Disclosure
The Register - Security
The Register - Security
L
LINUX DO - 热门话题
Webroot Blog
Webroot Blog
Google Online Security Blog
Google Online Security Blog
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
S
Security Affairs
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
云风的 BLOG
云风的 BLOG
博客园 - 叶小钗
T
Threatpost
Spread Privacy
Spread Privacy
小众软件
小众软件
AWS News Blog
AWS News Blog
S
Secure Thoughts
S
Security @ Cisco Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks

博客园 - treasurelife

java可以开发电脑桌面应用吗?java开发用什么软件? Word、execl及PPT文档中如何插入windows图标(转) windows系统自带图标文件存储方式、存放位置及使用方法全解析(转) 网络类型IPv4和IPv6什么意思?区别? 2:文档编辑生成目录相关方法说明 TCP与UDP的区别 vs 2012 InstallShield Limited Edition Project 打包windows服务解析 百科编辑器ueditor应用笔记 百度编辑器Ueditor 初始化加载内容失败解决办法 VS.Net中程序集的Debug版本和Release版本的区别(转) .NET中IDisposable接口的基本使用 (转) ADO.NET事物 string 是引用类型还是值类型(转) 索引(转) 聚集索引和非聚集索引 深入了解SQLServer系统数据库工作原理(转) - treasurelife - 博客园 什么是 CLR(转) 数据完整性 SQLServer数据库安全管理机制详解
.Net 中的序列化与反序列化 (转)
treasurelife · 2009-09-08 · via 博客园 - treasurelife
 

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

    二、对象的序列化主要有两种用途:
  
  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 调用不变。