Alles over serialisatie in Visual Basic

Serialisatie is het proces waarbij een object wordt omgezet in een lineaire reeks bytes die een 'bytestroom' wordt genoemd. Deserialisatie keert het proces gewoon om. Maar waarom zou je een object in een bytestream willen omzetten?

De belangrijkste reden is dat u het object kunt verplaatsen. Overweeg de mogelijkheden. Aangezien "alles een object" is in .NET, kunt u alles serialiseren en opslaan in een bestand. U kunt dus afbeeldingen, gegevensbestanden, de huidige status van een programmamodule serialiseren ('status' is als een momentopname van uw programma op een bepaald moment zodat u de uitvoering tijdelijk kunt onderbreken en later opnieuw kunt beginnen) ... wat u ook moet doen.

U kunt deze objecten ook op schijf opslaan in bestanden, ze verzenden via het web, ze doorgeven aan een ander programma, een back-up bewaren voor veiligheid of beveiliging. De mogelijkheden zijn letterlijk eindeloos.

Daarom is serialisatie zo'n sleutelproces in .NET en Visual Basic. Hieronder vindt u een gedeelte over aangepaste serialisatie door de ISerializable interface en codering a Nieuw en een GetObjectData subroutine.

Als een eerste voorbeeld van serialisatie, laten we een van de gemakkelijkste programma's doen, maar ook een van de meest bruikbare: het serialiseren van gegevens en vervolgens het deserialiseren van gegevens in eenvoudige klasse van en naar een bestand. In dit voorbeeld worden de gegevens niet alleen geserialiseerd, maar wordt ook de structuur van de gegevens opgeslagen. De structuur hier wordt verklaard in een module om dingen ... nou ja ... gestructureerd te houden.

Module SerializeParms
Public Class ParmExample
   Public Parm1Name As String = "Parm1 Name"
   Public Parm1Value As Integer = 12345
   Public Parm2Name As String
   Public Parm2Value As Decimal
Eindklasse
Einde module

Vervolgens kunnen individuele waarden worden opgeslagen in een bestand als dit:

Importeert System.Runtime.Serialization.Formatters.Binary
Importeert System.IO
Formulier openbare klasse 1
   Private Sub mySerialize_Click (_
      ByVal-afzender als 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 ()
   Einde Sub
Eindklasse

En dezelfde waarden kunnen als volgt worden opgehaald:

Importeert System.Runtime.Serialization.Formatters.Binary
Importeert System.IO
Formulier openbare klasse 1
   Private Sub myDeserialize_Click (_
      ByVal-afzender als 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)
   Einde Sub
Eindklasse

EEN Structuur of een verzameling (zoals een ArrayList) liever dan een Klasse kan ook op dezelfde manier in een bestand worden geserialiseerd.

Nu we het basale serialisatieproces hebben doorlopen, laten we eens kijken naar de specifieke details die deel uitmaken van het proces op de volgende pagina.

Een van de eerste dingen die u moet opvallen aan dit voorbeeld is het kenmerk in de Klasse. Attributen zijn gewoon meer informatie die u aan VB.NET kunt verstrekken over een object en ze worden voor veel verschillende dingen gebruikt. Het kenmerk in deze code vertelt VB.NET om extra code toe te voegen, zodat later alles in deze klasse kan worden geserialiseerd.

Als er specifieke items in de Klasse zijn die u gebruikt niet doen wilt worden geserialiseerd, kunt u de kenmerk om ze uit te sluiten:

Public Parm3Value As String = "Whatever"

In het voorbeeld is dat dat serialize en deserialize zijn methoden van de BinaryFormatter voorwerp (f in dit voorbeeld).

f.Serialize (s, ParmData)

Dit object neemt de Bestandsstroom object en het object dat als parameters moet worden geserialiseerd. We zullen zien dat VB.NET een ander object biedt waarmee het resultaat als XML kan worden uitgedrukt.

En een laatste opmerking, als uw object andere ondergeschikte objecten bevat, worden deze ook geserialiseerd! Maar sinds allemaal objecten die zijn geserialiseerd moet gemarkeerd zijn met de kenmerk, moeten al deze onderliggende objecten ook op die manier worden gemarkeerd.

Om volledig duidelijk te zijn wat er in uw programma gebeurt, wilt u misschien het bestand met de naam weergeven ParmData in Kladblok om te zien hoe geserialiseerde gegevens eruit zien. (Als u deze code hebt gevolgd, zou deze in de bin.Debug map in uw project.) Aangezien dit een binair bestand is, is de meeste inhoud geen leesbare tekst, maar u zou alle tekenreeksen in uw geserialiseerd bestand moeten kunnen zien. We zullen vervolgens een XML-versie maken en misschien wilt u de twee vergelijken om u bewust te zijn van het verschil.

Serialiseren naar XML in plaats van een binair bestand vereist zeer weinig wijzigingen. XML is niet zo snel en kan sommige objectinformatie niet vastleggen, maar het is veel flexibeler. XML kan tegenwoordig door vrijwel elke andere softwaretechnologie ter wereld worden gebruikt. Als u zeker wilt zijn dat uw bestandsstructuren u niet "binden" aan Microsoft, is dit een goede optie om naar te kijken. Microsoft benadrukt "LINQ to XML" om XML-gegevensbestanden te maken met hun nieuwste technologie, maar veel mensen geven nog steeds de voorkeur aan deze methode.

De 'X' in XML staat voor eXtensible. In ons XML-voorbeeld gaan we een van die extensies van XML gebruiken, een technologie genaamd ZEEP. Dit betekende vroeger "Simple Object Access Protocol" maar nu is het slechts een naam. (SOAP is zo opgewaardeerd dat de oorspronkelijke naam niet meer zo goed past.)

Het belangrijkste dat we in onze subroutines moeten veranderen, is de declinatie van de serialisatieformatter. Dit moet worden gewijzigd in zowel de subroutine die het object serialiseert als degene die het opnieuw deserialiseert. Voor de standaardconfiguratie houdt dit drie wijzigingen in uw programma in. Eerst moet u een referentie aan het project toevoegen. Klik met de rechtermuisknop op het project en selecteer Referentie toevoegen ... . Zorg ervoor dat…

System.Runtime.Serialization.Formatters.Soap

... is toegevoegd aan het project.

Wijzig vervolgens de twee instructies in het programma dat ernaar verwijst.

Importeert System.Runtime.Serialization.Formatters.Soap
Dim f As New SoapFormatter

Dit keer als je hetzelfde bekijkt ParmData bestand in Kladblok, zult u zien dat het hele ding in leesbare XML-tekst is, zoals ...

Parm1 Naam
12345
Parm2-naam
54.321,12345

Er is ook veel extra XML die ook nodig is voor de SOAP-standaard in het bestand. Als u wilt controleren wat de kenmerk doet, kunt u een variabele met dat kenmerk toevoegen en het bestand bekijken om te controleren of het niet is opgenomen.

In het voorbeeld dat we zojuist hebben gecodeerd, zijn alleen de gegevens geserialiseerd, maar stel dat u moet bepalen hoe de gegevens worden geserialiseerd. VB.NET kan dat ook!

Om dit te bereiken, moet je een beetje dieper ingaan op het concept van serialisatie. VB.NET heeft hier een nieuw doel om te helpen: SerializationInfo. Hoewel u de mogelijkheid hebt om aangepast serialisatiegedrag te coderen, brengt dit extra codering met zich mee.

De basis extra code wordt hieronder getoond. Vergeet niet dat deze klasse wordt gebruikt in plaats van de ParmExample klasse getoond in het vorige voorbeeld. Dit is geen volledig voorbeeld. Het doel is om u de nieuwe code te tonen die nodig is voor aangepaste serialisatie.

Importeert System.Runtime.Serialization
_
Public Class CustomSerialization
   Implementeert ISerializable
   gegevens worden hier geserialiseerd
   'Public SerializedVariabel als type
   Public Sub Nieuw ()
   'standaard constructor wanneer de klasse
   'is gemaakt - aangepaste code kan zijn
   hier ook toegevoegd
   Einde Sub
   Public Sub Nieuw (_
      ByVal-informatie als SerializationInfo, _
      ByVal-context als StreamingContext)
      initialiseer uw programmavariabelen van
      'een geserialiseerd gegevensarchief
   Einde Sub
   Public Sub GetObjectData (_
      ByVal-informatie als SerializationInfo, _
      ByVal-context als StreamingContext) _
      Implementeert ISerializable.GetObjectData
      'update het geserialiseerde gegevensarchief
      'uit programmavariabelen
   Einde Sub
Eindklasse

Het idee is dat je dat nu kunt (en in feite ook jij moet) alle gegevens bijwerken en lezen in het geserialiseerde gegevensarchief in de Nieuw en GetObjectData subroutines. U moet ook een generiek opnemen Nieuw constructor (geen parameterlijst) omdat u een interface implementeert.

De klasse heeft normaal gesproken ook formele eigenschappen en gecodeerde methoden ...

'Generieke eigendom
Prive newPropertyValue As String
Public Property NewProperty () As String
   Krijgen
      Retourneer newPropertyValue
   Einde ophalen
   Set (ByVal-waarde als tekenreeks)
      newPropertyValue = waarde
   Einde instellen
Einde eigendom
'Generieke methode
Public Sub MyMethod ()
   'methode code
Einde Sub

De resulterende geserialiseerde klasse kan unieke waarden in het bestand maken op basis van de code die u opgeeft. Een onroerendgoedklasse kan bijvoorbeeld de waarde en het adres van een huis bijwerken, maar de klasse zou ook een berekende marktclassificatie serialiseren.

De Nieuw subroutine ziet er ongeveer zo uit:

Public Sub Nieuw (_
   ByVal-informatie als SerializationInfo, _
   ByVal-context als StreamingContext)
   initialiseer uw programmavariabelen van
   'een geserialiseerd gegevensarchief
   Parm1Name = info.GetString ("a")
   Parm1Value = info.GetInt32 ("b")
   'Nieuwe sub gaat verder ...

Wanneer deserialize wordt genoemd op een BinaryFormatter object, deze sub wordt uitgevoerd en een SerializationInfo object wordt doorgegeven aan de Nieuw subroutine. Nieuw kan dan doen wat nodig is met de geserialiseerde gegevenswaarden. Bijvoorbeeld…

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

Het omgekeerde gebeurt wanneer serialize wordt genoemd, maar de BinaryFormatter object roept GetObjectData in plaats daarvan.

Public Sub GetObjectData (_
   ByVal-informatie als SerializationInfo, _
   ByVal-context als StreamingContext) _
   Implementeert ISerializable.GetObjectData
   'update het geserialiseerde gegevensarchief
   'uit programmavariabelen
   Als Parm2Name = "Test" Dan
      info.AddValue ("a", "Dit is een test.")
   Anders
      info.AddValue ("a", "Deze keer geen test.")
   Stop als
   info.AddValue ("b", 2)

Merk op dat de gegevens als naam / waarde-paren aan het geserialiseerde bestand worden toegevoegd.

Veel van de webpagina's die ik heb gevonden bij het schrijven van dit artikel, lijken geen echte werkcode te hebben. Men vraagt ​​zich af of de auteur daadwerkelijk enige code heeft uitgevoerd voordat het artikel soms werd geschreven.