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:
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 interfaceISerializable
),<XmlAttribute("Name")>
změní XML element z párového na nepárový a hodnota dané property bude v atributuName
. 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 7x (84.64 kB)
Aplikace je včetně zdrojových kódů v jazyce VB