Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 10 - Serializace a deserializace ve VB.NET

V minulé lekci, LINQ to XML ve VB.NET, jsme se naučili generovat, číst a editovat XML soubory pomocí technologie LINQ to XML a třídy XDocument.

V dnešním tutoriálu Soubory ve VB.NET si řekneme něco o serializaci a deserializaci.

Serializace je uchování stavu objektu. Jedná se o konvertování objektu na proud bytů a poté uložení někde do paměti, databáze nebo souboru. Deserializace je opak serializace. Jedná se o převedení proudu bytů zpět na kopii objektu.

K čemu je to dobré?

Serializace nám umožní uložit stav objektu. Pomocí deserializace si ho můžeme pak kdykoliv znovu vytvořit. Pomocí serializace se třeba posílají data skrz síť nebo se ukládá nastavení aplikace.

Ukázková aplikace

Založíme si nový projekt typu Windows Forms Application.

Třída Uzivatel

Do projektu přidáme nějakou třídu, jejíž instanci bychom chtěli zachovat a při opětovném spuštění aplikace ji mít ve stavu, v jakém jsme ji při zavření aplikace zanechali. Třídu nazveme Uzivatel a dáme jí vlastnosti Jmeno, Prijmeni a DatumNarozeni:

Public Class Uzivatel
    Public Property Jmeno As String
    Public Property Prijmeni As String
    Public Property DatumNarozeni As DateTime
End Class

Všimněme si, že je třída nastavena jako Public, aby jí deserializer mohl později nastavit.

Designer formuláře Form1

Na hlavní formulář si přidáme:

  • dva ovládací prvky typu TextBox na jméno a příjmení,
  • ovládací prvek DateTimePicker, abychom mohli určit datum uživatele,
  • tlačítko typu Button, kterým budeme přidávat uživatele do naší aplikace,
  • prvek ListBox pro zobrazení uživatelů.

Nakonec si přejmenujeme naše ovládací prvky ze základního jména na nějaké, abychom se v nich vyznali:

Pojmenování komponent ukázkové aplikace na serializaci ve Visual Studio - Soubory ve VB.NET

Kód formuláře Form1

Přesuneme se do kódu hlavního formuláře Form1, do kterého si dopíšeme privátní kolekci typu List(Of Uzivatel), abychom měli uživatele kde v aplikaci uchovávat:

Private uzivatele As List(Of Uzivatel) = New List(Of Uzivatel)

Designer formuláře Form1

Přesuneme se zpátky do designeru formuláře. Přidáme si metodu k události Click u ovládacího prvku btnPridej, do které napíšeme kód, který přidá uživatele do naší kolekce. Dále ještě musíme ukázat uživatele v prvku listBoxUzivatele, k čemuž nám poslouží vlastnost DataSource:

Private Sub btnPridej_Click(sender As Object, e As EventArgs) Handles btnPridej.Click
    ' Vytvoříme nového uživatele s daty z našich komponent
    Dim uzivatel As Uzivatel = New Uzivatel With {
        .Jmeno = tbJmeno.Text,
        .Prijmeni = tbPrijmeni.Text,
        .DatumNarozeni = dateTimePicker.Value
    }
    ' Přidáme ho do naší kolekce
    uzivatele.Add(uzivatel)
    ' Obnovíme zdroj dat našeho listBoxuUzivatele
    listBoxUzivatele.DataSource = Nothing
    listBoxUzivatele.DataSource = uzivatele
End Sub

Třída Uzivatel

Teď již máme vcelku funkční aplikaci. Když aplikaci spustíme a zkusíme uživatele přidat, uvidíme, že se přidala vlastně jen položka "NazevProjektu.Uzivatel". Přesuneme se tedy do třídy Uzivatel a přepíšeme metodu ToString():

Public Overrides Function ToString() As String
    Return "Jméno: " + Jmeno + " Příjmení: " + Prijmeni + " Datum Narození: " + DatumNarozeni.ToShortDateString()
End Function

Testování

Zkusme si přidat uživatele teď. Vidíme, že se uživatel zobrazuje lidštěji :-)

Serializace

Nyní konečně můžeme přejít k serializaci dat. Přesuneme se do kódu formuláře.

Kód formuláře Form1

Zde si napíšeme metodu Serializuj():

Private Sub Serializuj()
    Try
        ' Vytvoříme si XmlSerializer na typ List(Of Uzivatel)
        Dim serializer As XmlSerializer = New XmlSerializer(uzivatele.GetType())

        ' Alternativní forma, jak by to šlo také zapsat
        'Dim serializer As XmlSerializer = New XmlSerializer(GetType(List(Of Uzivatel)))

        ' Vytvoříme Stream pomocí kterého budeme serializovat
        Using sw As StreamWriter = New StreamWriter("uzivatele.xml")
            ' Zavoláme metodu Serialize, kde první parametr je Stream
            ' Ten jsme vyvtořili o řádek výše
            ' Druhý parametr je objekt, který serializujeme
            serializer.Serialize(sw, uzivatele)
        End Using
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

Využili jsme serializer do formátu XML. Serializerů je několik typů včetně binárního. Poskytuje nám je již připravené .NET framework. Nemusíme se tedy o nic starat, instance se serializují automaticky.

Designer formuláře Form1

Nyní se přesuneme do designeru a u formuláře najdeme Event (událost) OnClosing, 2x klikneme a v obslužném kódu zavoláme naší metodu Serializuj():

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    Serializuj()
End Sub

Název metody se může lišit podle názvu hlavního formuláře. Jestli jste jeho jméno neupravovali, budete mít na začátku nejspíš prefix Form1.

Testování

Když nyní spustíme program, přidáme nějaké uživatele a program zavřeme. Kolekce uživatelů se serializuje a uloží do NazevProjektu/Bin/Debug/uzivatele.xml. Když soubor otevřeme, bude vypadat takto:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfUzivatel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Uzivatel>
    <Jmeno>Jan</Jmeno>
    <Prijmeni>Novák</Prijmeni>
    <DatumNarozeni>1998-02-10T10:47:19</DatumNarozeni>
  </Uzivatel>
  <Uzivatel>
    <Jmeno>Jakub</Jmeno>
    <Prijmeni>Špatný</Prijmeni>
    <DatumNarozeni>2000-11-21T17:29:45</DatumNarozeni>
  </Uzivatel>
</ArrayOfUzivatel>

Deserializace

Serializaci máme, tak teď ještě deserializaci. Z pohledu kódu je to trošku těžší, proto si raději všechno vysvětlíme ještě jednou.

Kód formuláře Form1

V kódu hlavního formuláře si napíšeme metodu Deserializuj():

Private Sub Deserializuj()
    Try
        If File.Exists("uzivatele.xml") Then
            Dim serializer As XmlSerializer = New XmlSerializer(uzivatele.GetType())
            Using sr As StreamReader = New StreamReader("uzivatele.xml")
                uzivatele = CType(serializer.Deserialize(sr), List(Of Uzivatel))
            End Using
        Else
            Throw New FileNotFoundException("Soubor nebyl nalezen")
        End If
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

Nejprve musíme zjistit, jestli vůbec daný XML soubor s daty existuje. K tomu nám poslouží třída File a její metoda Exists(), do které napíšeme cestu k našemu souboru. Metoda vrací Boolean. Do těla podmínky vložíme XmlSerializer na typ naší kolekce uživatelů. Dále vytvoříme StreamReader s cestou k našemu souboru.

Pak zavoláme metodu Deserialize() z třídy XmlSerializer. Metoda Deserialize() vrací Object. Musíme zde tedy přetypovat, než přiřadíme uložené uživatele k našim stávajícím.

Designer formuláře Form1

Přejdeme do designeru formuláře. V Properties (vlastnostech) formuláře najdeme událost Load a vytvoříme její obslužnou metodu. V ní zavoláme naši metodu Deserializuj() a načteme naše uživatele do ovládacího prvku ListBox:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Deserializuj()
    listBoxUzivatele.DataSource = uzivatele
End Sub

Název metody se může lišit podle názvu hlavního formuláře. Jestli jste jeho jméno neupravovali, budete mít na začátku nejspíš prefix Form1.

Testování

Aplikaci spustíme, naplníme daty, zavřeme a znovu otevřeme. Vidíme, že obsahuje všechny uživatele, které jsme tam přidali :-)

Závěr

Třída, kterou serializujeme, musí obsahovat bezparametrický konstruktor (nebo žádný parametrický). Je to z toho důvodu, že deserializer si nejdříve vytvoří prázdnou instanci a potom postupně zadává vlastnosti, jak je čte ze souboru (nebo jiného streamu).

Nemůžeme serializovat ovládací prvky, ať již defaultní, anebo námi vytvořené (User Control).

K serializaci patří několik atributů např.:

  • <XmlIgnore> - nebude danou propertu serializovat,
  • <Serializable()> - dává se nad deklaraci třídy a určuje objekt k serializaci (Implementuje interface ISerializable),
  • <XmlAttribute("Name")> změní XML element z párového na nepárový a hodnota dané property bude v atributu Name. Například <Uzivatel Name="Jan"> místo <Jmeno>Jan</Jmeno>.

V následujícím cvičení, Řešené úlohy k 6.-10. lekci práce se soubory ve VB.NET, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 6x (84.64 kB)
Aplikace je včetně zdrojových kódů v jazyce VB

 

Předchozí článek
LINQ to XML ve VB.NET
Všechny články v sekci
Soubory ve VB.NET
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 6.-10. lekci práce se soubory ve VB.NET
Článek pro vás napsal Dominik Horváth
Avatar
Uživatelské hodnocení:
2 hlasů
Autor se věnuje programování v jazycích VB.NET a C#.
Aktivity