Mikuláš je tu! Získaj 90 % extra kreditov ZADARMO s promo kódom CERTIK90 pri nákupe od 1 199 kreditov. Len do nedele 7. 12. 2025! Zisti viac:
NOVINKA: Najžiadanejšie rekvalifikačné kurzy teraz s 50% zľavou + kurz AI ZADARMO. Nečakaj, táto ponuka dlho nevydrží! Zisti viac:

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

V predchádzajúcej 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 kurze C# .NET 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 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. Vytvorme 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"> namiesto <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 na pridanie používateľa do našej aplikácie.
  • Prvok ListBox s názvom usersListBox na zobrazenie použí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 používateľa v prvku usersListBox. Na to 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(), ktorej:

  • 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

Spustíme aplikáciu, pridáme nejakých použí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. Na to 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 použí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 takto:

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 použí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 používateľov, ktorých sme tam pridali:

Výpis použí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 deserializér 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é 7x (87.46 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:
14 hlasov
H̴̢̡̛̫̙̖̦͍̥̺̳̪͖̺̫̲͇̗̹̠̥͈̭͔̻̗͚̭̥̝͐̋͒̆̾̅͒̈̐̀̒̔̇̈̔̆̎̔͐̊͆̆̐̊̈͆̂̐̓̓͛̌̈́̈́̅̅̔̚̕̚͠͝͝͝͝ì̸͇͖̹̯̤͇͍̹̥̅͗͆̄̌͆͑̓̈́̓̊̈́͋̈́͛͊͛͂̇͋͒̿̃͐͌̐̚͝͝͝͝͝͝.̶̧̡̧̧̖̫̯̞͖̯̩̠̭̩͇͔̤̱̜̠̠̙͉͉̼̱͓̣͍̱͎͕̦͓̫̗̮̦͍͚̗͕̥̳͚̬̯̞̟͇̻̺̙͙̜͖̰̊͒̌̌̚͜͜͝
Aktivity