Staňte se programátorem: Napište si vlastní adresář II.

Po čase se vracíme k našemu seriálu o programování v C#. Dnes si opět napíšeme jednoduchý adresář kontaktů, namísto XML databáze ale použijeme serializaci objektů.

Po delší pauze se vracíme k našemu seriálu o programování ve Visual C#, který se od těch ostatních liší především v tom, že pod každým článkem najdete odkaz ke stažení kompletních zdrojových kódu včetně projektu, a pokud je vám programování naprosto cizí nabídneme vám i spustitelný program, který vám jasně napoví, o čem celý článek byl.

Náš zdrojový kód je optimalizovaný pro nejnovější vývojové prostředí Visual C# 2008 Express, které si může každý stáhnout zdarma ze serveru Microsoftu. Programovat v C# tedy může skutečně každý.

V našem seriálu jsme už programovali:

A k adresáři kontaktů se vrátíme i před vánočními svátky. Zatímco minule program kontakt ukládal do strukturovaného XML souboru, tentokráte budeme ukládat objekty přímo do souboru pomocí tzv. serializace. To má jednu podstatnou výhodu. Data nemusíme složitě parsovat, do souboru se totiž uloží celá instance třídy včetně dat.

Screen004.png Screen005.png
Správce kontaktů a obsah souboru s uloženými serializovanými kontakty

Snad ještě snadnější je v takovém případě obnova – instance třídy se načtou do pole přímo ze souboru, stačí tedy napsat tři řádky zdrojového kódu a s objekty můžete běžně pracovat.

V dnešním díle si tedy naučíte:

  • Pracovat s generickými kolekcemi
  • Serializovat a deserializovat objekty, vytvoření serializovatelného typu

Generické kolekce

Generické kolekce jsou novinkou Microsoft .NET 2.0 Frameworku. Jsou to takové kolekce, kde si sami definujete datový typ, se kterým bude kolekce operovat – tedy datový typ ukládaného objektu musí být totožný s datovým typem, se kterým jsme generickou kolekci deklarovali.

Díky tomu odpadá nutnost explicitního přetypovávání, jak je tomu u negenerických kolekcí, které vracejí vždy typ System.Object. Díky generickým kolekcím budeme moci snadno celou třídu serializovat.

Složité? Nevadí, schválně porovnejte následující dvě varianty zdrojového kódu. Poprvé použijeme negenerické koekce, podruhé pak naopak generické kolekce.

Použití negenerické kolekce ArrayList by vypadalo takto:

// Naplní ArrayList
ArrayList kontakty = new ArrayList();
konktakty.Add(new Kontakt(....)); // Lze vkládat cokoli...

// Pro získání požadované hodnoty musíme přetypovat vrácený typ Object na typ Kontakt
Kontakt k = (Kontakt)kontakty[0];

V našem programu využíváme kolekci System.Collections.Generic.List což je generická obdoba třídy ArrayList:

List<Kontakt> kontakty = new List<Kontakt>();
kontakty.Add(new Kontakt(...));// Lze vkládat pouze instance třídy Kontakt

// Není nutné přetypování – bude vždy vrácena instance třídy Kontakt.
Kontakt k = kontakty[0];

Jak na serializaci

Všechny objekty, které v našem programu vytvoříme, mají krátkou životnost – jsou vytvořeny konstruktorem či tovární metodou a z paměti jsou odstraněny garbage collectorem v době jejich nepoužívání či po ukončení programu. Chceme-li uchovat objekty jako sekvenci bitů ve formě souboru na disku, použijeme serializaci, kdy se námi vybraný objekt převede na datový proud představovaný třídou System.IO.Stream a tím pádem může být uložen do souboru či poslán přes síť na zcela jiný počítač.

Při opačném procesu (deserializaci) bude v paměti vytvořen klon objektu, který byl do souboru uložen. Chceme-li, aby byl náš datový typ schopen serializace, je nutné mu přiřadit atribut [System.Serializable]. Jako ukázka nám poslouží datový typ Kontakt z adresáře kontaktů:

[Serializable]
public class Kontakt
{
  public string Skupina;
  public string Nick;
  public string Jmeno;
  public string Telefon;
  public string ICQ;
  public string Adresa;
  public string Poznamka;
  public string Obr;

  public Kontakt(string skupina, string nick, string jmeno,string telefon,
                                     string ICQ, string adresa, string poznamka, string obr)
  {
    this.Skupina = skupina;
    this.Nick = nick;
    this.Jmeno = jmeno;
    this.Telefon = telefon;
    this.ICQ = ICQ;
    this.Adresa = adresa;
    this.Poznamka = poznamka;
    this.Obr = obr;
  }
}

V adresáři kontaktů bude pomocí serializace ukládána generická kolekceSystem.Collections.Generic.List obsahující instance typu Kontakt. Pro vykonání prací spojených se serializací nám poslouží třída System.Runtime. Serialization.Formatters.Binary.BinaryFormatter. Pro serializaci objektu musíme nejprve vytvořit instanci datového typu System.IO.FileStream představující datový tok dat do souboru, kam bude uložen serializovaný objekt. Následně zavoláme metodu Serialize třídy BinaryFormatter, která jako první argument očekává datový proud k souboru a jako druhý argument serializovaný objekt.

MujTyp serializovanyObjekt = new MujTyp(...);
BinaryFormatter f = new BinaryFormatter();
Stream st = new FileStream(@“C:\....“, FileMode.Create);
f.Serialize(st, serializovanyObjekt);

Pro zpětnou deserializaci použijeme metodu Deserialize třídy BinaryFormatter, která jako argument očekává datový proud k souboru, jež obsahuje serializovaná data, která jsou vrácena jako datový typ System.Object.

BinaryFormatter b = new BinaryFormatter();
Stream st = new FileStream(@“C:\....“, FileMode.Open);
kontakty = (MujTyp)b.Deserialize(st);

Dnešní projekt se tedy na první pohled neliší od toho, který pro ukládání kontaktů používal XML soubor. Vnitřně je ale zcela odlišný a snad i jednodušší. Zatímco v případě XML se hodnoty kontaktů ukládaly do textového souboru, v případě serializace se informace ukládají do binárního souboru, který obsahuje jak data, tak informaci o tom, co je to za proměnné, objekty aj.

Zejména u velkého množství dat může být XML mnohem náročnější na zpracování a na disku také zabere mnohem více místa, na druhou stranu je ale snadno interpretovatelný jinými programy a vlastně i pouhým pohledem, oproti binárnímu zápisu je totiž snadno čitelný i člověkem.

Ke spuštění přeloženého programu budete potřebovat novější Microsoft .NET Framework, k otevření projektu se zdrojovýmí kódy pak Microsoft Visual Studio nebo Visual C# 2008 Express.

Diskuze (4) Další článek: Wikipedia volá na pomoc: potřebujeme ještě 2 000 000 dolarů

Témata článku: , , , , , , , , , , , , , , ,