IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

10. diel - Serializácia a deserializácia v C# .NET

V minulej lekcii, LINQ to XML v C# .NET, sme sa naučili generovať, čítať, editovať a mazať dáta v XML súboroch pomocou technológie LINQ to XML.

V C# .NET tutoriále budeme konvertovať objekt na prúd bytov, ktorý prevedieme späť na kópiu objektu. Naučíme sa teda serializovať a deserializovať objekt.

Úvod do serializácie a deserializácie

Serializácia je uchovanie stavu objektu. Trochu odbornejšie by sa to dalo popísať ako konvertovanie objektu na prúd bytov a potom uloženie niekde do pamäte, databázy alebo súboru. Deserializácia je opak serializácie. Dalo by sa povedať, že teda prevedieme prúd bytov späť na kópiu objektu.

Využitie

Serializácia nám umožňuje uložiť stav objektu a potom pomocou deserializácie si ho kedykoľvek znova vytvoriť. Pomocou serializácie sa napríklad posielajú dáta cez sieť alebo sa ukladá nastavenie aplikácie.

Serializácia

Než sa pustíme do vlastnej konverzie objektu na prúd bytov, pripravíme si aplikáciu. Založme si aplikáciu typu Windows Forms Application s názvom SerializationSample.

Trieda User

Do aplikácie si pridáme túto verejnú triedu User, ktorej inštancie budeme chcieť zachovať:

[Serializable()]
public class User
{
    [XmlAttribute("FirstName")]
    public string FirstName { get; set; }

    [XmlAttribute("LastName")]
    public string LastName { get; set; }

    [XmlAttribute("BirthDate")]
    public DateTime BirthDate { get; set; }

    public override string ToString()
    {
        return "First name: " + FirstName +
               "Last name: " + LastName +
               "Birth date: " + BirthDate.ToShortDateString();
    }

}

Triedu anotujeme atribútom [Serializable()], ktorým hovoríme, že jej inštancie budeme chcieť serializovať. Ďalej pridáme vlastnosti:

  • FirstName,
  • LastName,
  • BirthDate.

Všetky vlastnosti anotujeme atribútom [XmlAttribute("Name")], ktorý zmení XML element z párového na nepárový a hodnota danej vlastnosti bude v atribúte Name. Napríklad <User FirstName="John"> miesto <FirstName>John</FirstName>. Nakoniec prepíšeme metódu ToString().

Keby sme mali v triede vlastnosť, ktorú by sme nechceli serializovať, anotovali by sme ju atribútom [XmlIgnore].

Hlavný formulár

Ukážme si podobu hlavného formulára, ktorý si vzápätí popíšeme:

Pomenovanie komponentov ukážkovej aplikácie na serializáciu vo Visual Studio - Súbory v C# .NET

Na hlavný formulár si pridáme:

  • Dva prvky TextBox s názvom firstNameTextBox a lastNameTextBox na meno a priezvisko.
  • Prvok DateTimePicker s názvom birthDateDateTimePicker pre dátum narodenia.
  • Tlačidlo s názvom addButton pre pridanie užívateľa do našej aplikácie.
  • Prvok ListBox s názvom usersListBox pre zobrazenie užívateľov.

Ovládacie prvky sme si premenovali z vygenerovaných názvov na také názvy, v ktorých sa vyznáme.

Kód hlavného formulára

Presunieme sa do kódu hlavného formulára, kam budeme písať všetok ďalší kód.

Kolekcia používateľov

Pred vygenerovaným konštruktorom si vytvoríme privátnu kolekciu users typu List<User>:

private List<User> users = new List<User>();

Obslužná metóda prvku addButton

Presunieme sa do dizajnéra hlavného formulára, kde si pridáme metódu k udalosti Click ovládacieho prvku addButton. V kóde hlavného formulára si dopíšeme telo vygenerovanej obslužnej metódy prvku addButton:

private void addButton_Click(object sender, EventArgs e)
{
    User user = new User
    {
        FirstName = firstNameTextBox.Text,
        LastName = lastNameTextBox.Text,
        BirthDate = birthDateDateTimePicker.Value
    };

    users.Add(user);
    usersListBox.DataSource = null;
    usersListBox.DataSource = users;
}

Najprv vytvoríme nového používateľa s dátami z našich kontroliek. Potom ho pridávame do našej kolekcie users. Nakoniec ešte musíme obnoviť zdroj dát nášho užívateľa v prvku usersListBox. K tomu nám poslúži vlastnosť DataSource.

Testovanie

Spustite si aplikáciu. Skúsme si pridať len jedného používateľa, aby sme si boli istí, že nám aplikácia funguje.

Serializácia dát

Teraz konečne môžeme prejsť na serializáciu dát. V kóde hlavného formulára si napíšeme metódu Serialize():

private void Serialize()
{
    try
    {
        XmlSerializer serializer = new XmlSerializer(users.GetType());

        using (StreamWriter sw = new StreamWriter("users.xml"))
        {
            serializer.Serialize(sw, users);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

V bloku try vytvoríme inštanciu serializer typu XmlSerializer na kolekcii typu List<User>. Potom vytvoríme stream sw typu StreamWriter, pomocou ktorého budeme serializovať. Potom voláme metódu Serialize(), ktoré:

  • v prvom parametri odovzdáme náš stream sw,
  • v druhom parametri odovzdáme našu kolekciu users, ktorej dáta chceme serializovať.

V bloku catch vypíšeme prípadnú vzniknutú výnimku.

Teraz sa vrátime späť do designera. Pri formulári nájdeme Event (udalosť) OnClosing, na ktorú dvakrát klikneme. Vo vygenerovanej metóde v kóde hlavného formulára zavoláme našu metódu Serialize():

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    Serialize();
}

Testovanie

Spustite aplikáciu, pridajme nejakých užívateľov a potom aplikáciu zatvoríme. Kolekcia používateľov sa serializuje a uloží do priečinka s aplikáciou na ceste .../bin/Debug/users.xml. Keď súbor otvoríme, uvidíme zapísané dáta:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfUser xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <User>
    <FirstName>John</FirstName>
    <LastName>Smith</LastName>
    <BirthDate>2014-09-05T23:09:19</BirthDate>
  </User>
  <User>
    <FirstName>James</FirstName>
    <LastName>Brown</LastName>
    <BirthDate>2014-09-05T23:09:19</BirthDate>
  </User>
</ArrayOfUser>

Deserializácie

Serializáciu máme, tak teraz ešte deserializáciu. Z pohľadu na kód je to trošku ťažšie a preto si radšej všetko vysvetlíme ešte raz. Najprv si do kódu hlavného formulára napíšeme metódu Deserialize():

private void Deserialize()
{
    try
    {
        if (File.Exists("users.xml"))
        {
            XmlSerializer serializer = new XmlSerializer(users.GetType());
            using (StreamReader sr = new StreamReader("users.xml"))
            {
                users = (List<User>)serializer.Deserialize(sr);
            }
        }
        else throw new FileNotFoundException("File not found");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Najprv musíme zistiť, či vôbec daný XML súbor s dátami existuje. K tomu nám poslúži trieda File a jej metóda Exists(string path), ktorá vracia hodnotu typu bool. V tele podmienky vytvoríme serializer typu XmlSerializer na typ List našej kolekcie používateľov.

Ďalej vytvoríme StreamReader s cestou k nášmu súboru. Potom zavoláme metódu Deserialize() z triedy XmlSerializer. Je tu ale drobný detail, a to že metóda Deserialize() vracia object. Musíme tu teda pretypovať na List<User>, než priradíme uložených užívateľov k našim existujúcim.

Teraz prejdeme do dizajnéra hlavného formulára. Vo vlastnostiach (properties) formulára nájdeme udalosť Load, ku ktorej si necháme vygenerovať obslužnú metódu, ktorej telo vyplníme nasledovne:

private void Form1_Load(object sender, EventArgs e)
{
    Deserialize();
    usersListBox.DataSource = users;
}

V tele metódy zavoláme našu metódu Deserialize(). Potom ešte načítame našich užívateľov do nášho prvku ListBox.

Testovanie

Spustíme aplikáciu, naplníme kolekciu dátami a aplikáciu zatvoríme. Potom ju znovu otvoríme a uvidíme, že obsahuje všetkých užívateľov, ktorých sme tam pridali:

Výpis pouzívateľov deserializáciou - Súbory v C# .NET

Záver

Trieda, ktorú serializujeme, musí obsahovať bezparametrický konštruktor, alebo žiadny parametrický. Je to z toho dôvodu, že deserializer si najskôr vytvorí prázdnu inštanciu a potom postupne zadáva vlastnosti, ako ich číta zo súboru alebo iného streamu. Nemôžeme serializovať ovládacie prvky, či už defaultné alebo nami vytvorené (User Control).

V nasledujúcom cvičení, Riešené úlohy k 6.-10. lekcii práce so súbormi v C# .NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 0x (86.98 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
LINQ to XML v C# .NET
Všetky články v sekcii
Súbory v C# .NET
Preskočiť článok
(neodporúčame)
Riešené úlohy k 6.-10. lekcii práce so súbormi v C# .NET
Článok pre vás napísal Jan Vargovský
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
H̴̢̡̛̫̙̖̦͍̥̺̳̪͖̺̫̲͇̗̹̠̥͈̭͔̻̗͚̭̥̝͐̋͒̆̾̅͒̈̐̀̒̔̇̈̔̆̎̔͐̊͆̆̐̊̈͆̂̐̓̓͛̌̈́̈́̅̅̔̚̕̚͠͝͝͝͝ì̸͇͖̹̯̤͇͍̹̥̅͗͆̄̌͆͑̓̈́̓̊̈́͋̈́͛͊͛͂̇͋͒̿̃͐͌̐̚͝͝͝͝͝͝.̶̧̡̧̧̖̫̯̞͖̯̩̠̭̩͇͔̤̱̜̠̠̙͉͉̼̱͓̣͍̱͎͕̦͓̫̗̮̦͍͚̗͕̥̳͚̬̯̞̟͇̻̺̙͙̜͖̰̊͒̌̌̚͜͜͝
Aktivity