有关在Visual Basic中进行序列化的所有信息

Serialization is the process of converting an object into a linear sequence of bytes called a "byte stream." Deserialization just reverses the process. But why would you want to convert an object into a byte stream?

序列化是将对象转换为线性字节序列的过程,称为“字节流”。 反序列化只是逆转了这一过程。 但是,为什么要将一个对象转换为字节流?

The main reason is so you can move the object around. Consider the possibilities. Since "everything is an object" in .NET, you can serialize anything and save it to a file. So you could serialize pictures, data files, the current state of a program module ('state' is like a snapshot of your program at a point in time so you could temporarily suspend execution and start again later) ... whatever you need to do.

主要原因是可以移动对象。 考虑可能性。 由于.NET中的“一切都是对象”,因此您可以序列化任何内容并将其保存到文件中。 因此,您可以序列化图片,数据文件,程序模块的当前状态(“状态”就像某个时间点上的程序快照一样,因此可以暂时中止执行并稍后再启动)...做。

You can also store these objects on disk in files, send them over the web, pass them to a different program, keep a backup copy for safety or security. The possibilities are quite literally endless.

您也可以将这些对象存储在磁盘上的文件中,通过网络发送它们,将它们传递给其他程序,以确保安全性。 从字面上看,可能性是无限的。

That's why serialization is such a key process in .NET and Visual Basic. Below is a section on custom serialization by implementing the ISerializable interface and coding a New and a GetObjectData subroutine.

这就是为什么序列化是.NET和Visual Basic中如此关键的过程的原因。 下面是通过实现ISerializable接口并编码NewGetObjectData子例程来进行自定义序列化的部分。

As a first example of serialization, let's do one of the easiest programs, but also one of the most useful: serializing data, and then deserializing data in simple class to and from a file. In this example, the data is not only serialized, but the structure of the data is saved too. The structure here is declared in a module to keep things ... well ... structured.

作为序列化的第一个示例,让我们做一个最简单的程序,同时也是最有用的程序之一:序列化数据,然后在简单类中与文件反序列化数据。 在此示例中,数据不仅被序列化,而且数据的结构也被保存。 这里的结构在模块中声明,以保持事物的良好结构。

Module SerializeParms<Serializable()> Public Class ParmExample   Public Parm1Name As String = "Parm1 Name"   Public Parm1Value As Integer = 12345   Public Parm2Name As String   Public Parm2Value As DecimalEnd ClassEnd Module

Module SerializeParms <Serializable()>公共类ParmExample公共Parm1Name作为字符串=“ Parm1 Name”公共Parm1Value作为整数= 12345 Public Parm2Name作为字符串公共Parm2Value作为DecimalEnd ClassEnd模块

Then, individual values can be saved to a file like this:

然后,可以将各个值保存到这样的文件中:

Imports System.Runtime.Serialization.Formatters.BinaryImports System.IOPublic Class Form1   Private Sub mySerialize_Click( _      ByVal sender As System.Object, _      ByVal e As System.EventArgs) _      Handles mySerialize.Click      Dim ParmData As New ParmExample      ParmData.Parm2Name = "Parm2 Name"      ParmData.Parm2Value = 54321.12345      Dim s As New FileStream("ParmInfo", FileMode.Create)      Dim f As New BinaryFormatter      f.Serialize(s, ParmData)      s.Close()   End SubEnd Class

导入System.Runtime.Serialization.Formatters.BinaryImports System.IOPublic类Form1私有子mySerialize_Click(_ ByVal发送者作为System.Object,_ ByVal e作为System.EventArgs)_处理mySerialize.Click昏暗ParmData作为新的ParmExample ParmData.Parm2Name =“ Parm2名称“ ParmData.Parm2Value = 54321.12345 Dim作为新FileStream(” ParmInfo“,FileMode.Create)Dim作为新BinaryFormatter f.Serialize(s,ParmData)s.Close()End SubEnd Class

And those same values can be retrieved like this:

这些相同的值可以像这样检索:

Imports System.Runtime.Serialization.Formatters.BinaryImports System.IOPublic Class Form1   Private Sub myDeserialize_Click( _      ByVal sender As System.Object, _      ByVal e As System.EventArgs) _      Handles myDeserialize.Click      Dim s = New FileStream("ParmInfo", FileMode.Open)      Dim f As New BinaryFormatter      Dim RestoredParms As New ParmExample      RestoredParms = f.Deserialize(s)      s.Close()      Console.WriteLine(RestoredParms.Parm1Name)      Console.WriteLine(RestoredParms.Parm1Value)      Console.WriteLine(RestoredParms.Parm2Name)      Console.WriteLine(RestoredParms.Parm2Value)   End SubEnd Class

导入System.Runtime.Serialization.Formatters.BinaryImports System.IOPublic类Form1私有子myDeserialize_Click(_ ByVal发送者作为System.Object,_ ByVal e作为System.EventArgs)_处理myDeserialize.Click昏暗=新FileStream(“ ParmInfo”, FileMode.Open)Dim f如新BinaryFormatter Dim RestoredParms如新ParmExample RestoredParms = f.Deserialize(s)s.Close()Console.WriteLine(RestoredParms.Parm1Name)Console.WriteLine(RestoredParms.Parm1Value)Console.WriteLine(RestoredParms.Parm1Value) )Console.WriteLine(RestoredParms.Parm2Value)End SubEnd类

A Structure or a collection (such as an ArrayList) rather than a Class could also be serialized to a file this same way.

结构或集合(例如ArrayList )而不是也可以以相同的方式序列化到文件。

Now that we have gone over the basic serializing process, lets look at the specific details that are part of the process on the next page.

现在,我们已经完成了基本的序列化过程,让我们在下一页上查看作为过程一部分的特定细节。

One of the first things you should notice about this example is the <Serializable()> attribute in the Class. Attributes are just more information that you can provide to VB.NET about an object and they're used for a lot of different things. The attribute in this code tells VB.NET to add extra code so that later on, everything in this class can be serialized.

关于此示例,首先要注意的事情之一是Class中<Serializable()>属性。 属性只是您可以提供给VB.NET的有关对象的更多信息,它们用于许多不同的事情。 这段代码中的属性告诉VB.NET添加额外的代码,以便以后可以对此类中的所有内容进行序列化。

If there are specific items in the Class that you don't want to be serialized, you can use the <NonSerialized()> attribute to exclude them:

如果在类特定项目,你不想被序列化,你可以使用<非序列化()>属性将它们排除在外:

<NonSerialized()> Public Parm3Value As String = "Whatever"

<NonSerialized()>公共Parm3Value作为String =“ Whatever”

In the example, notice is that Serialize and Deserialize are methods of the BinaryFormatter object (f in this example).

在示例中,请注意, SerializeDeserializeBinaryFormatter对象(在此示例中为f )的方法。

f.Serialize(s, ParmData)

f。序列化(s,ParmData)

This object takes the FileStream object and the object to be serialized as parameters. We'll see that VB.NET offers another object that allows the result to be expressed as XML.

该对象将FileStream对象和要序列化的对象作为参数。 我们将看到VB.NET提供了另一个对象,该对象允许将结果表示为XML。

And one final note, if your object includes other subordinate objects, they'll be serialized too! But since all objects that are serialized must be marked with the <Serializable()> attribute, all of these child objects must be marked that way too.

最后一点,如果您的对象包括其他从属对象,它们也将被序列化! 但是,由于所有序列化的对象都必须使用<Serializable()>属性进行标记,因此所有这些子对象也必须以这种方式进行标记。

Just to be completely clear about what is happening in your program, you might want to display the file named ParmData in Notepad to see what serialized data looks like. (If you followed this code, it should be in the bin.Debug folder in your project.) Since this is a binary file, most of the content isn't readable text, but you should be able to see any strings in your serialized file. We'll do an XML version next and you might want to compare the two just to be aware of the difference.

为了完全清楚程序中发生的事情,您可能希望在记事本中显示名为ParmData的文件,以查看序列化数据的外观。 (如果遵循此代码,则它应位于项目的bin.Debug文件夹中。)由于这是一个二进制文件,所以大多数内容都不是可读的文本,但是您应该能够看到序列化的任何字符串文件。 接下来,我们将做一个XML版本,您可能想比较两者,以了解它们之间的区别。

Serializing to XML instead of a binary file requires very few changes. XML isn't as fast and can't capture some object information, but it's far more flexible. XML can be used by just about any other software technology in the world today. If you want to be sure your file structures don't "tie you into" Microsoft, this is a good option to look into. Microsoft is emphasizing "LINQ to XML" to create XML data files in their latest technology but many people still prefer this method.

序列化为XML而不是二进制文件需要很少的更改。 XML并没有那么快,不能捕获某些对象信息,但是它要灵活得多。 当今世界上几乎所有其他软件技术都可以使用XML。 如果您要确保文件结构不会“束缚” Microsoft,那么这是一个不错的选择。 Microsoft一直在强调“ LINQ to XML”以其最新技术创建XML数据文件,但是许多人仍然喜欢这种方法。

The 'X' in XML stands for eXtensible. In our XML example, we're going to use one of those extensions of XML, a technology called SOAP. This used to mean "Simple Object Access Protocol" but now it's just a name. (SOAP has been upgraded so much that the original name doesn't fit that well anymore.)

XML中的“ X”表示e X可扩展。 在我们的XML示例中,我们将使用XML的一种扩展,一种称为SOAP的技术。 这曾经是“简单对象访问协议”的意思,但现在只是一个名称。 (SOAP已经进行了太多升级,以至于原来的名称已经不合适了。)

The main thing that we have to change in our subroutines is the declation of the serialization formatter. This has to be changed in both the subroutine that serializes the object and the one that deserializes it again. For the default configuration, this involves three changes to your program. First, you have to add a Reference to the project. Right-click the project and select Add Reference .... Make sure ...

我们必须在子例程中更改的主要内容是对序列化格式化程序的声明。 必须在序列化对象的子例程和再次反序列化该对象的子例程中对此进行更改。 对于默认配置,这涉及对程序的三处更改。 首先,您必须添加对项目的引用。 右键单击项目,然后选择添加引用...。 确保 ...

System.Runtime.Serialization.Formatters.Soap

System.Runtime.Serialization.Formatters.Soap

... has been added to the project.

...已添加到项目中。

Then change the two statements in the program that references it.

然后在引用它的程序中更改两个语句。

Imports System.Runtime.Serialization.Formatters.SoapDim f As New SoapFormatter

将System.Runtime.Serialization.Formatters.SoapDim导入为新的SoapFormatter

This time, if you check out the same ParmData file in Notepad, you'll see that the whole thing is in readable XML text such as ...

这次,如果您在记事本中签出相同的ParmData文件,您将看到整个内容都在可读的XML文本中,例如...

<Parm1Name id="ref-3">Parm1 Name</Parm1Name><Parm1Value>12345</Parm1Value><Parm2Name id="ref-4">Parm2 Name</Parm2Name><Parm2Value>54321.12345</Parm2Value>

<Parm1Name id =“ ref-3”> Parm1名称</ Parm1Name> <Parm1Value> 12345 </ Parm1Value> <Parm2Name id =“ ref-4”> Parm2名称</ Parm2Name> <Parm2Value> 54321.12345 </ Parm2Value>

There is also a lot of additional XML there that's necessary for the SOAP standard in the file as well. If you want to verify what the <NonSerialized()> attribute does, you can add a variable with that attribute and look at the file to verify that it's not included.

文件中还有很多其他的XML,这些都是SOAP标准所必需的。 如果要验证<NonSerialized()>属性的作用,则可以添加带有该属性的变量,然后查看文件以确认其中不包含该变量。

The example we just coded only serialized the data, but suppose you need to control how the data is serialized. VB.NET can do that too!

我们刚刚编码的示例仅对数据进行了序列化,但是假设您需要控制如何对数据进行序列化。 VB.NET也可以做到这一点!

To accomplish this, you need to get a little deeper into the concept of serialization. VB.NET has a new object to help out here: SerializationInfo. Although you have the ability to code custom serialization behavior, it comes with a cost of extra coding.

为此,您需要更深入地了解序列化的概念。 VB.NET在这里有一个新对象可以帮助您: SerializationInfo 。 尽管您可以对自定义序列化行为进行编码,但是它会带来额外的编码成本。

The basic extra code is shown below. Remember, this class is used instead of the ParmExample class shown in the earlier example. This isn't a complete example. The purpose is to show you the new code that is needed for custom serialization.

基本的额外代码如下所示。 请记住,使用该类代替了先前示例中显示的ParmExample类。 这不是一个完整的示例。 目的是向您展示自定义序列化所需的新代码。

Imports System.Runtime.Serialization<Serializable()> _Public Class CustomSerialization   Implements ISerializable   ' data to be serialized here   ' Public SerializedVariable as Type   Public Sub New()   ' default constructor when the class   ' is created - custom code can be   ' added here too   End Sub   Public Sub New( _      ByVal info As SerializationInfo, _      ByVal context As StreamingContext)      ' initialize your program variables from      ' a serialized data store   End Sub   Public Sub GetObjectData( _      ByVal info As SerializationInfo, _      ByVal context As StreamingContext) _      Implements ISerializable.GetObjectData      ' update the serialized data store      ' from program variables   End SubEnd Class

导入System.Runtime.Serialization <Serializable()> _Public类CustomSerialization实现ISerializable'要在此处序列化的数据'Public SerializedVariable作为Type Public Sub New()'创建类'时的默认构造函数-也可以在此处添加自定义代码End Sub Public Sub New(_ SubVal info As SerializationInfo,_ ByVal context As StreamingContext)'从'序列化数据存储区初始化您的程序变量End Sub Public Sub GetObjectData(_ ByVal info As SerializationInfo,_ ByVal context As StreamingContext)_实现ISerializable .GetObjectData'从程序变量End SubEnd类'更新序列化的数据存储'

The idea is that now you can (and, in fact, you must) do all of the updating and reading of data in the serialized data store in the New and GetObjectData subroutines. You must also include a generic New constructor (no parameter list) because you're implementing an interface.

这个想法是,现在您可以(实际上,您必须 )在NewGetObjectData子例程中完成序列化数据存储中所有数据的更新和读取。 您还必须包括通用的New构造函数(无参数列表),因为您要实现接口。

The class will normally have formal properties and methods coded as well ...

该类通常也具有形式化的属性和编码的方法。

' Generic PropertyPrivate newPropertyValue As StringPublic Property NewProperty() As String   Get      Return newPropertyValue   End Get   Set(ByVal value As String)      newPropertyValue = value   End SetEnd Property' Generic MethodPublic Sub MyMethod()   'method codeEnd Sub

'通用PropertyPrivate newPropertyValue作为StringPublic属性NewProperty()作为字符串Get返回newPropertyValue End Get Set(ByVal值作为字符串)newPropertyValue =值End SetEnd属性'Generic MethodPublic Sub MyMethod()'方法codeEnd Sub

The resulting serialized class can create unique values in the file based on the code you supply. For example, a real-estate class might update a the value and address of a house but the class would serialize a calculated market classification as well.

生成的序列化类可以根据您提供的代码在文件中创建唯一值。 例如,房地产类别可能会更新房屋的价格和地址,但该类别也会序列化计算出的市场分类。

The New subroutine will look something like this:

New子例程将如下所示:

Public Sub New( _   ByVal info As SerializationInfo, _   ByVal context As StreamingContext)   ' initialize your program variables from   ' a serialized data store   Parm1Name = info.GetString("a")   Parm1Value = info.GetInt32("b")   ' New sub continues ...

Public Sub New(_ ByVal info作为SerializationInfo,_ ByVal context作为StreamingContext)'从'序列化数据存储Parm1Name = info.GetString(“ a”)Parm1Value = info.GetInt32(“ b”)'初始化您的程序变量继续...

When Deserialize is called on a BinaryFormatter object, this sub is executed and a SerializationInfo object is passed to the New subroutine. New can then do whatever is necessary with the serialized data values. For example ...

BinaryFormatter对象上调用反序列化时 ,将执行此子程序,并将SerializationInfo对象传递给New子例程。 然后,New可以对序列化的数据值执行任何必要的操作。 例如 ...

MsgBox("This is Parm1Value Times Pi: " _   & (Parm1Value * Math.PI).ToString)

MsgBox(“这是Parm1Value Times Pi:” _&(Parm1Value * Math.PI).ToString)

The reverse happens when Serialize is called, but the BinaryFormatter object calls GetObjectData instead.

当调用Serialize ,但是BinaryFormatter对象却调用GetObjectData时,情况正好相反。

Public Sub GetObjectData( _   ByVal info As SerializationInfo, _   ByVal context As StreamingContext) _   Implements ISerializable.GetObjectData   ' update the serialized data store   ' from program variables   If Parm2Name = "Test" Then      info.AddValue("a", "This is a test.")   Else      info.AddValue("a", "No test this time.")   End If   info.AddValue("b", 2)

Public Sub GetObjectData(_ ByVal info as SerializationInfo,_ ByVal context As StreamingContext)_实现ISerializable.GetObjectData'从程序变量更新序列化的数据存储'如果Parm2Name =“ Test”然后info.AddValue(“ a”,“这是一个测试。”)其他info.AddValue(“ a”,“这次不测试。”)如果info.AddValue(“ b”,2)结束

Notice that the data is added to the serialized file as name/value pairs.

请注意,数据将作为名称/值对添加到序列化文件中。

A lot of the web pages I've found in writing this article don't seem to have actual working code. One wonders whether the author actually executed any code before writing the article sometimes. 

我在撰写本文时发现的许多网页似乎没有实际的工作代码。 一个人想知道作者有时在写文章之前是否实际执行过任何代码。

翻译自: https://www.thoughtco.com/all-about-serializing-in-visual-basic-3424466

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值