Allt om serialisering i Visual Basic

Serialisering är processen för att konvertera ett objekt till en linjär sekvens av byte som kallas en "byte-ström." Deserialisering vänder bara processen. Men varför skulle du vilja konvertera ett objekt till en byte-ström?

Det främsta skälet är att du kan flytta objektet runt. Tänk på möjligheterna. Eftersom "allt är ett objekt" i .NET kan du serialisera vad som helst och spara det i en fil. Så du kan serialisera bilder, datafiler, det aktuella läget för en programmodul ("tillstånd" är som en ögonblicksbild av ditt program vid en tidpunkt så att du tillfälligt kan stänga av körningen och starta igen senare) ... vad du behöver göra.

Du kan också lagra dessa objekt på disken i filer, skicka dem över webben, skicka dem till ett annat program, behålla en säkerhetskopia för säkerhet eller säkerhet. Möjligheterna är bokstavligen oändliga.

Därför är serialisering en sådan nyckelprocess i .NET och Visual Basic. Nedan följer ett avsnitt om anpassad serialisering genom att implementera ISerializable gränssnitt och kodning a Ny och a GetObjectData subrutin.

Som ett första exempel på serialisering, låt oss göra ett av de enklaste programmen, men också ett av de mest användbara: att serialisera data och sedan deserialisera data i enkel klass till och från en fil. I det här exemplet är data inte bara serialiserade, utan strukturen för data sparas också. Strukturen här förklaras i en modul för att hålla saker ... väl ... strukturerad.

Modul SerializeParms
Public Class ParmExample
   Public Parm1Name As String = "Parm1 Name"
   Public Parm1Value As Integer = 12345
   Public Parm2Name som sträng
   Public Parm2Value As Decimal
Slutklass
Slutmodul

Sedan kan enskilda värden sparas i en fil som denna:

Importerar system.Runtime.Serialization.Formatters.Binary
Importerar System.IO
Public Class Form1
   Privat sub mySerialize_Click (_
      ByVal avsändare som system.Objekt, _
      ByVal e As System.EventArgs) _
      Hanterar mySerialize.Click
      Dim ParmData som ny ParmExample
      ParmData.Parm2Name = "Parm2-namn"
      ParmData.Parm2Value = 54321.12345
      Dim s Som ny FileStream ("ParmInfo", FileMode.Create)
      Dim f Som ny BinaryFormatter
      f.Serialize (s, ParmData)
      s.Close ()
   Avsluta under
Slutklass

Och samma värden kan hämtas så här:

Importerar system.Runtime.Serialization.Formatters.Binary
Importerar System.IO
Public Class Form1
   Privat sub myDeserialize_Click (_
      ByVal avsändare som system.Objekt, _
      ByVal e As System.EventArgs) _
      Hanterar myDeserialize.Click
      Dim s = New FileStream ("ParmInfo", FileMode.Open)
      Dim f Som ny 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)
   Avsluta under
Slutklass

EN Strukturera eller en samling (t.ex. en Arraylist) snarare än a Klass kan också serialiseras till en fil på samma sätt.

Nu när vi har gått igenom den grundläggande serialiseringsprocessen, låt oss titta på de specifika detaljerna som ingår i processen på nästa sida.

En av de första sakerna du bör märka med detta exempel är attribut i Klass. Attribut är bara mer information som du kan ge VB.NET om ett objekt och de används för många olika saker. Attributet i den här koden berättar för VB.NET att lägga till extra kod så att allt senare i serien kan serialiseras.

Om det finns specifika objekt i klassen som du inte Vill du bli seriell, kan du använda attribut för att utesluta dem:

Public Parm3Value As String = "Whatever"

I exemplet är meddelandet det Serialisera och avserialisera är metoder för BinaryFormatter objekt (f i det här exemplet).

f.Serialize (s, ParmData)

Detta objekt tar Filestream objekt och objektet som ska serialiseras som parametrar. Vi ser att VB.NET erbjuder ett annat objekt som gör att resultatet kan uttryckas som XML.

Och en sista anmärkning, om ditt objekt innehåller andra underordnade objekt, kommer de också att serialiseras! Men eftersom Allt objekt som är serialiserade måste markeras med attribut, måste alla dessa barnobjekt också markeras på det sättet.

Bara för att vara helt klar över vad som händer i ditt program, kanske du vill visa filen som heter ParmData i Anteckningar för att se hur seriell information ser ut. (Om du följde den här koden borde den finnas i bin.Debug -mappen i ditt projekt.) Eftersom det här är en binär fil är det mesta av innehållet inte läsbar text, men du bör kunna se några strängar i din seriefil. Vi gör en XML-version nästa och du kanske vill jämföra de två bara för att vara medveten om skillnaden.

Serialisering till XML istället för en binär fil kräver mycket få ändringar. XML är inte lika snabbt och kan inte fånga lite objektinformation, men det är mycket mer flexibelt. XML kan användas av nästan alla andra programvarutekniker i världen idag. Om du vill vara säker på att dina filstrukturer inte "binder dig till" Microsoft, är detta ett bra alternativ att undersöka. Microsoft betonar "LINQ till XML" för att skapa XML-datafiler i sin senaste teknik, men många föredrar fortfarande den här metoden.

"X" i XML står för eXTÄNJBAR. I vårt XML-exempel kommer vi att använda en av dessa tillägg av XML, en teknik som heter TVÅL. Det brukade betyda "Simple Object Access Protocol" men nu är det bara ett namn. (SOAP har uppgraderats så mycket att det ursprungliga namnet inte passar så bra längre.)

Det viktigaste som vi måste ändra i våra subroutiner är deklareringen av serieformatformatorn. Detta måste ändras i både subrutinen som serielliserar objektet och den som deserialiserar det igen. För standardkonfigurationen innebär detta tre ändringar av ditt program. Först måste du lägga till en referens till projektet. Högerklicka på projektet och välj Lägg till referens ... . Se till ...

System.Runtime.Serialization.Formatters.Soap

... har lagts till i projektet.

Ändra sedan de två uttalandena i programmet som refererar till det.

Importerar system.Runtime.Serialization.Formatters.Soap
Dim f As New SoapFormatter

Den här gången, om du kolla in detsamma ParmData fil i Notepad, ser du att det hela är i läsbar XML-text som ...

Parm1-namn
12345
Parm2-namn
54321,12345

Det finns också mycket extra XML där som är nödvändigt för SOAP-standarden i filen också. Om du vill verifiera vad attribut gör, kan du lägga till en variabel med attributet och titta på filen för att verifiera att den inte ingår.

Exemplet vi bara kodade bara serialiserade data, men antar att du måste kontrollera hur informationen serielliseras. VB.NET kan göra det också!

För att åstadkomma detta måste du gå lite djupare in i konceptet med serialisering. VB.NET har ett nytt objekt att hjälpa till här: SerializationInfo. Även om du har förmågan att koda anpassat serialiseringsbeteende kommer det med en kostnad för extra kodning.

Det grundläggande extra koden visas nedan. Kom ihåg att den här klassen används istället för ParmExample klass som visas i det tidigare exemplet. Detta är inte ett komplett exempel. Syftet är att visa dig den nya koden som behövs för anpassad seriegivning.

Importerar system.Runtime.Serialization
_
Offentlig klass CustomSerialization
   Implementerar ISerialiserbar
   "data som ska serialiseras här
   'Public SerializedVariable as Type
   Public Sub New ()
   'standardkonstruktör när klassen
   "skapas - anpassad kod kan vara
   "lagt till här också
   Avsluta under
   Public Sub New (_
      ByVal info Som SerializationInfo, _
      ByVal-sammanhang som StreamingContext)
      initialisera dina programvariabler från
      "en seriell datalager
   Avsluta under
   Public Sub GetObjectData (_
      ByVal info Som SerializationInfo, _
      ByVal-sammanhang som StreamingContext) _
      Implementerar ISerializable.GetObjectData
      "uppdatera den seriella datalageren
      "från programvariabler
   Avsluta under
Slutklass

Tanken är att nu kan du (och i själva verket du måste) gör all uppdatering och läsning av data i det seriellt datalagret i Ny och GetObjectData subrutiner. Du måste också inkludera en generisk Ny konstruktör (ingen parameterlista) eftersom du implementerar ett gränssnitt.

Klassen kommer normalt också att ha formella egenskaper och metoder kodade ...

"Generisk egendom
Privat newPropertyValue As String
Offentlig egendom NewProperty () Som sträng
   Skaffa sig
      Returnera newPropertyValue
   Slut Get
   Ställ in (ByVal-värde som sträng)
      newPropertyValue = värde
   Slutuppsättning
Slut egendom
Generisk metod
Public Sub MyMethod ()
   metodkod
Avsluta under

Den resulterande serialiserade klassen kan skapa unika värden i filen baserat på koden du anger. Till exempel kan en fastighetsklass uppdatera ett husets värde och adress, men klassen skulle också serialisera en beräknad marknadsklassificering.

De Ny subrutin ser ut så här:

Public Sub New (_
   ByVal info Som SerializationInfo, _
   ByVal-sammanhang som StreamingContext)
   initialisera dina programvariabler från
   "en seriell datalager
   Parm1Name = info.GetString ("a")
   Parm1Value = info.GetInt32 ("b")
   "Ny sub fortsätter ...

När avserialisera kallas på en BinaryFormatter objekt, denna sub körs och a SerializationInfo objektet skickas till Ny subrutin. Nytt kan sedan göra vad som krävs med de seriella datavärdena. Till exempel…

MsgBox ("Detta är Parm1Value Times Pi:" _
   & (Parm1Value * Math.PI) .ToString)

Det omvända händer när Serialisera kallas, men BinaryFormatter objekt samtal GetObjectData istället.

Public Sub GetObjectData (_
   ByVal info Som SerializationInfo, _
   ByVal-sammanhang som StreamingContext) _
   Implementerar ISerializable.GetObjectData
   "uppdatera den seriella datalageren
   "från programvariabler
   Om Parm2Name = "Test" sedan
      info.AddValue ("a", "Detta är ett test.")
   Annan
      info.AddValue ("a", "Inget test den här gången.")
   Sluta om
   info.AddValue ("b", 2)

Lägg märke till att data läggs till i den serialiserade filen som namn / värdepar.

Många av webbsidorna som jag har hittat när jag skriver den här artikeln verkar inte ha någon faktisk kod. Man undrar om författaren verkligen körde någon kod innan han skrev artikeln ibland.