Poznáváme C# a Microsoft.NET 40. díl – serializace

Dnešní díl se začneme věnovat serializaci. Vysvětlíme si co tento pojem znamená, jak vytvářet serializovatelné typy a jakými způsoby tyto typy serializovat.

Co je to serializace?

Mnoho instancí, které při svém programování používáme mají celkem krátký „život“. Jsou nějakou cestou (konstruktorem, skrze reflexi, tovární metodou…) vytvořeny, po té jsou nějakým způsobem použity a pak když nejsou potřeba (neexistuje na ně jakákoliv reference)  jsou při úklidu (Garbage collection) Garbage collectorem odstraněny z paměti. Ovšem, ne všechny instance jsou používány takto krátce a některé instance nesoucí potřebná data potřebujeme zachovat na delší dobu. To dokážeme zařídit tak, že onu instanci uložíme do nějakého perzistentního úložiště (relační databáze, soubor..). Takovémuto uložení instance do perzistentního úložiště se říká Serializace.  V podstatě jde o to, že instance je převedena na Stream, tím pádem může být, jak již bylo řečeno, uložena, ale také díky tomu, že je Streamem, i poslána např. pomocí HTTP protokolu na zcela jiný počítač. Serializovatelné typy, musí být i ty, které jsou používány při takzvaném remotingu, což je možnost používat objekty mezi různými aplikačními doménami. Opačnému procesu, tedy procesu pří kterém je z nějakého proudu vytvořena instance, se naopak říká Deserializace.

Jak učinit typy serializovatelnými?

K tomu, abychom naše typy učinili serializovatelnými (schopnými se serializovat) vedou dvě cesty. První cestou je použití atributu System.Serializable, což je cesta jednodušší a v obvyklých aplikacích častěji používaná. Druhým způsobem je nechat námi vytvářený typ implementovat rozhraní System.ISerializable. My se dnes budeme zabývat použitím atributu Serializable. V případě použití tohoto atributu na náš typ se o průběh serializace instance tohoto typu kompletně postará běhové prostředí .NET runtime. Takže pokud bychom chtěli mít třídu představující osobu a chtěli bychom, aby bylo možné instance této třídy serializovat, provedeme to jednoduše takto :

/// <summary>
/// Ukazkova trida predstavujici osobu, jejiz instance mohou byt serializovany
/// </summary>
[Serializable]
public class Osoba
{
 private DateTime datumNarozeni;
 private string jmeno;
 private string prijmeni;

 public Osoba(string Jmeno, string Prijmeni, DateTime DatumNarozeni)
 {
  this.jmeno = Jmeno;
  this.prijmeni = Prijmeni;
  this.datumNarozeni = DatumNarozeni;
 }

 //zbytek tridy
}

V případě této výchozí serializace ( = použití atributu Serializable) jsou serializovány všechny datové členy daného typu a to včetně těch soukromých. Je důležité vědět, že všechny typy, kterých jsou datové členy daného typu musí být taktéž serializovatelné. Pokud by tomu tak nebylo a pokusili bychom se o serializaci, došlo by k vyhození výjimky System.Runtime.Serialization.SerializationException.

/// <summary>
/// Tato trida by nemohla byt serialozovana protoze obahuje datovy clen
/// ktery nelze serializovat
/// </summary>
[Serializable]
public class NemoznaSerializace
{
 NeserializovatelnyTyp clen;
}

public struct NeserializovatelnyTyp
{
 //implementace typu
}

I když je třída označena atributem Serializable, její datový člen není a proto ji nelze serializovat. V případě naší ukázkové třídy Osoba, není se serializací problém, protože všechny typy datových členů (String a DateTime), jejichž definici obsahuje, jsou označeny jako serializovatelné.

Jak instanci serializovat?

Nyní když víme jakým způsobem učinit typ serializovatelným a také jaké je potřeba dodržet pravidla, potřebujeme ještě vědět jak vlastní serializaci provedeme. Ve jmenném prostoru System.Runtime.Serialization se nachází rozhraní IFormatter, které předepisuje funkcionalitu pro formátování serializovaných objektů. Přesněji, obsahuje předpis pro metody Serialize a Deserialize, které zařizují, jak název napovídá, vlastní serializaci respektive deserializaci. V základní knihovně tříd .NET frameworku jsou pro naše použití k dispozici dvě základní implementace tohoto rozhraní a to třídy BinaryFormatter a SoapFormatter.

 

Klepněte pro větší obrázek

 

BinaryFormatter je implementace, která serializuje a desearilizuje objekty v binárním formátu a nalezneme ji ve jmenném prostoru System.Runtime.Serialization.Formatters.Binary. SoapFormatter zase serializuje a deserializuje objekty do formátu SOAP, což je v podstatě implementace XML a nachází se ve jmenném prostoru System.Runtime.Serialization.Formatters.Soap. Následující příklad demostruje použití serializace instance třídy Osoba do binárního formátu, tedy pomocí třídy BinaryFormatter.

public static void Serializace()
{
 DateTime lDate = new DateTime(1984,2,9);
 Osoba lOsoba = new Osoba("Jan","Novak",lDate);
Stream lStream = new FileStream("C:/test.bin",FileMode.Create);
 IFormatter lFormatter = new BinaryFormatter();
 try
 {
  lFormatter.Serialize(lStream,lOsoba);
 }
 finally
 {
  lStream.Close();
 }

}

Metodě Serialize předáme ve formě parametrů referenci na Stream, který vede ke konkrétnímu úložišti a samotnou instanci, kterou chceme serializovat. V našem případě jsme nechali instanci serializovat do souboru. A jak instanci deseralizujeme? To už ukazuje tento příklad :

public static void Deserializace()
{
 IFormatter lFormatter = new BinaryFormatter();
 Stream lStream = new FileStream("C:/test.bin",FileMode.Open);
 Osoba lOsoba = null;
 try
 {
  lOsoba = (Osoba) lFormatter.Deserialize(lStream);
  Console.WriteLine("Deserializovana osoba je {0} {1}",lOsoba.Jmeno,lOsoba.Prijmeni);
 }
 finally
 {
  lStream.Close();
 }
}

Deserializace instance je také velmi jednoduchá záležitost. Jediné co metodě Deserialize musíme předat je odkaz na Stream vedoucí k úložišti instance.

Pokud bychom chtěli instanci serializovat do formátu SOAP, jediné co bude ve zdrojovém kódu jiné bude záměna použité instance třídy BinaryFormatter za instanci třídy SoapFormatter. Obecně platí, že pro serializaci do souboru je vhodnější použít binární formát, protože výsledný soubor je o dost menší a mimo to také výrazně rychlejší.

Příští díl bude opět pojednávat o serializaci. Dozvíme se jak mít serializaci více pod kontrolou a zjistíme, že není nutné serializovat všechny datové členy instance typu.

Zdrojové kódy k příkladům naleznete zde.

Diskuze (2) Další článek: Chystá se senzační akvizice: hodlá eBay spolknout Skype Technologies?

Témata článku: Software, Microsoft, Programování, Reference, Stream, Jediný způsob, Soap, SERIALIZE, Krátký život, Public, Jediná cesta, Garbage, Private, Microsoft NET, Díl


Určitě si přečtěte

Přehled aprílových vtípků 2021: Ajťáci se dnes opět neberou vážně

Přehled aprílových vtípků 2021: Ajťáci se dnes opět neberou vážně

** Výběr nejlepších aprílových vtípků 2021 ** Článek postupně aktualizujeme ** Pokud sami nějaký objevíte, podělte se v komentářích

Lukáš Václavík | 23

Lukáš Václavík
AprílBulvár a vtípky
Korona hra: zvládli byste pandemii lépe než naše vláda? Zkuste si to ve webovém simulátoru

Korona hra: zvládli byste pandemii lépe než naše vláda? Zkuste si to ve webovém simulátoru

** Máte pocit, že naše vláda nezvládá boj s koronavirem? ** Poradili byste si se situací lépe než Andrej Babiš a Jan Blatný? ** Zkuste si to v českém webovém simulátoru Korona hra!

Karel Kilián | 74

Karel Kilián
COVID-19ČeskoHry
Nová volitelná aktualizace opravuje více než 40 chyb v operačním systému Windows 10
Karel Kilián
Windows UpdateAktualizaceWindows 10
Superinteligenci nedokážeme ovládat a nejspíše se nedozvíme, že už tam někde je

Superinteligenci nedokážeme ovládat a nejspíše se nedozvíme, že už tam někde je

** Firmy i organizace včetně EU připravují etické kodexy pro A.I. ** Vědci z Madridu zkoumali, jestli je budeme moci aplikovat na A.I. 2.0 ** A je tu háček, superinteligence pro nás totiž bude neuchopitelná

Jakub Čížek | 85

Jakub Čížek
Umělá inteligence
Když e-mail nestačí: šest způsobů, jak poslat velký soubor nebo video

Když e-mail nestačí: šest způsobů, jak poslat velký soubor nebo video

** Potřebujete poslat velký soubor, který se „nevejde“ do e-mailu? ** Pak máte několik možností, jak dostat data k jejich příjemci ** Podívejte se na šest způsobu, jak poslat velký soubor nebo video

Karel Kilián | 43

Karel Kilián
SouborÚložištěCloud
Jak stáhnout video z Youtube: 5 nejlepších nástrojů

Jak stáhnout video z Youtube: 5 nejlepších nástrojů

** Videa nejen z Youtube se hodí stáhnout v případě, že může být smazáno ** Rovněž se hodí možnost získat pouze audio ** Použít lze desktopové aplikace, webové nástroje i doplňky

Stanislav Janů | 32

Stanislav Janů
TipyNejlepší programy