laborator 05 - serializare

35

Click here to load reader

Upload: ana-maria

Post on 03-Jan-2016

147 views

Category:

Documents


2 download

DESCRIPTION

c#

TRANSCRIPT

Page 1: Laborator 05 - Serializare

111/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

SerializareSerializare5

Page 2: Laborator 05 - Serializare

211/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Ce este serializarea?Ce este serializarea? Serializarea este procesul prin care

convertim un obiect intr-o secventa liniara de bytes (octeti) care poate fi stocata sau transferata.

Deserializarea este procesul invers serializarii.

Page 3: Laborator 05 - Serializare

311/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Ce este serializarea?Ce este serializarea?

Page 4: Laborator 05 - Serializare

411/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum serializam un obiect?Cum serializam un obiect? PAS1: Cream un stream spre care vom directiona

serializarea. PAS2: Cream un obiect BinaryFormatter PAS3: Folosim metoda BinaryFormatter.Serialize

ex: string data = “data de salvat”; FileStream fs = new FileStream (“data.out”,

FileMode.Create); BinaryFormatter bf = new

BinaryFormatter(); bf.Serialize(fs,data); fs.Close();

Page 5: Laborator 05 - Serializare

511/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum deserializam un Cum deserializam un obiect?obiect? PAS1: Cream un stream din care vom citi PAS2: Cream un obiect BinaryFormatter PAS3: Cream un obiect in care vom salva datele

deserializate PAS4: Apelam metoda BinaryFormatter.Deserialize

ex: FileStream fs = new FileStream(“data.out”,

FileMode.Open); BinaryFormatter bf = new BinaryFormatter(); string data = (string)bf.Deserialize(fs); fs.Close();

Page 6: Laborator 05 - Serializare

611/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum cream clase ce pot fi Cum cream clase ce pot fi serializate?serializate? Pentru ca o clasa sa fie serializabila

trebuie adaugat atributul [Serializable] la clasa.

Putem controla serializarea si deserializarea pentru a obtine rezultatele dorite.

Page 7: Laborator 05 - Serializare

711/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

ex: [Serializable] class ObiectCumparat { public int productID; public decimal pret; public int cantitate; public decimal total; public ObiectCumparat(int productID, decimal

pret, int cantitate) { this.productID = productID; this.pret = pret; this.cantitate = cantitate; total = pret*cantitate; } }

Page 8: Laborator 05 - Serializare

811/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum oprim serializarea Cum oprim serializarea unor anumiti membri?unor anumiti membri? Observam ca variabila total este calculata prin

inmultirea valorilor pret si cantitate, deci stocarea sa pe disc este inutila si va ocupa spatiu suplimentar.

Putem in schimba sa actualizam aceasta variabila dupa deserializare.

Pentru a realiza acest lucru platforma .NET contine: atributul [NonSerialized] pe care il punem inaintea definiri

variabilei si care va instrui serializatorul sa nu o serializeze interfata IDeserializationCallback ce contine metoda

IDeserializationCallback.OnDeserialization ce va fi apelata cand se termina deserializarea.

Page 9: Laborator 05 - Serializare

911/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

clasa ObiectCumparat devine: [Serializable] class ObiectCumparat: IDeserializationCallback { public int productID; public decimal pret; public int cantitate; [NonSerialized] public decimal total; public ObiectCumparat(int productID, decimal pret, int cantitate) { this.productID = productID; this.pret = pret; this.cantitate = cantitate; total = pret*cantitate; }

void IDeserializationCallback .OnDeserialization(Object sender) { total = price * cantitate; } }

Page 10: Laborator 05 - Serializare

1011/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

VersionareVersionare O problema ce poate sa apara la serializare este

compatibilitatea cu versiunile anterioare. Daca versiunea 1.0 a aplicatiei noaste foloseste un format de clasa si versiunea 1.1 mai adauga un camp ce va fi serializat/deserializat pot sa apara probleme.

Pentru a rezolva problema putem folosi atributul [OptionalField] pt. membrii noi adaugati.

Acesta nu afecteaza procesul de serializare. La deserializare daca nu va fi gasit in streamul de intrare runtime-ul nu va da eroare dar va seta valoarea variabilei optionale ca null sau valoarea default pentru tipul respectiv.

Page 11: Laborator 05 - Serializare

1111/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

In versiunea 1.1 a clasei ObiectCumparat aceasta va avea urmatoarea forma:

[Serializable] class ObiectCumparat: IDeserializationCallback { public int productID; public decimal pret; public int cantitate; [NonSerialized] public decimal total; [OptionalField]public int taxe;

public ObiectCumparat(int productID, decimal pret, int cantitate) { this.productID = productID; this.pret = pret; this.cantitate = cantitate; total = pret*cantitate; }

void IDeserializationCallback .OnDeserialization(Object sender) { total = price * cantitate; } }

Page 12: Laborator 05 - Serializare

1211/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

VersionareVersionare Sfaturi pentru o versionare corecta:

Nu eliminati niciodata un camp serializat dintr-o versiune mai noua

Niciodata nu aplicati atributul NotSerialized la o variabila la care nu era aplicat in o versiune anterioara

Cand adaugati un camp nou declarati-l optional. Cand stergeti atributul NotSerialized adaugati

atributul OptionalField Initializati la deserializare toate campurile optionale

cu valori folositoare pentru aplicatia voastra.

Page 13: Laborator 05 - Serializare

1311/26/07L4 .NET ADF - (C) Victor Adrian Prisacariu

Alegerea unui format de Alegerea unui format de serializareserializare Platforma .NET include mai multe

metode de formatare a datelor serializate: BinaryFormatter: cea mai eficienta metoda

de serializare date in .NET SoapFormatter: format bazat pe XML

folositor pentru schimbul in retea de fisiere. Are sanse mai mari sa treaca de firewall-uri decat BinaryFormatter.

Page 14: Laborator 05 - Serializare

1411/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Alegerea unui format de Alegerea unui format de serializareserializare In general este recomandat sa folositi

BinaryFormatter cand stiti ca toate aplicatiile ce vor deserializa sunt construite folosind platforma .NET.

Folositi SOAPFormatter atunci cand doriti sa trimiteti datele serializate prin retea.

Page 15: Laborator 05 - Serializare

1511/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

SOAPFormatterSOAPFormatter Pentru a folosi SOAPFormatter procedati exact ca la

BinaryFormatter.

ex: FileStream fs = new FileStream(“data.in”,

FileMode.Open); SOAPFormatter bf = new SOAPFormatter(); string data = (string)bf.Deserialize(fs); fs.Close(); Pentru a obtine compatibiliate maxima intre aplicatia

voastra si alte aplicatii ce vor deserializa datele puteti folosi atribute prin care sa controlati formatul datelor scrise in stream-ul de iesire. Pentru mai multe detali cititi la pagina 280 in cartea .NET .

Page 16: Laborator 05 - Serializare

1611/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Serializare XMLSerializare XML XML este un format standardizat, bazat pe

text, pentru stocarea unor informatii ce pot fi citite usor de aplicatii.

XML foloseste un format de organizare a datelor de tip arborescent.

XML poate fi folosit pentru stocarea oricarui tip de date inclusiv documente, imagini, filme, muzica, etc.

.NET framework ofera mai multe biblioteci pentru citire si scriere fisiere XML

Page 17: Laborator 05 - Serializare

1711/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cand folosim serializare Cand folosim serializare XML?XML? Este recomandat sa folositi serializarea XML

atunci cand doriti interoperatibilitate, mai exact atunci cand doriti ca fisierele produse sau modificate de aplicatia voastra sa fie usor citibile de aplicatii ce nu sunt scrise in .NET

In consecinta serializare XML are urmatoarele avantaje: Interoperatibilitate mai mare Fisierele pot fi editate usor cu editoare normale

text Versionare mai usoara

Page 18: Laborator 05 - Serializare

1811/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum serializam XML un Cum serializam XML un obiect?obiect? PAS1: Crearea unui stream care va tine obiectul serializat

(sau a unui TextWriter sau a unui XmlWriter) PAS2: Crearea unui obiect XmlSerializer ce va primi ca

parametru la constructor un tipul obiectului pe care il vom serializa

PAS3: Apelarea metodei XmlSerializer.Serialize

ex: FileStream fs = new

FileStream(“data.out”,FileMode.Create); XmlSerializer xmls = new XmlSerializer(typeof(DateTime)); xmls.Serialize(fs,DateTime.Now); fs.Close();

Page 19: Laborator 05 - Serializare

1911/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum deserializam XML un Cum deserializam XML un obiect?obiect? PAS1: Creare stream de unde vom citi datele serializate PAS2: Creare obiect XmlSerializer (cu parametru la

constructor tipul obiectului de deserializat) PAS3: Apelarea metodei XmlSerializer.Deserialize

ex: FileStream fs = new

FileStream(“data.out”,FileMode.Create); XmlSerializer xmlDs = new

XmlSerializer(typeof(DateTime)); DateTime dataTrecuta = (DateTime)xmlDs.Deserialize(fs); fs.Close();

Page 20: Laborator 05 - Serializare

2011/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum cream clase ce pot fi Cum cream clase ce pot fi serializate XML?serializate XML? Conditiile pe care trebuie sa le

indeplineasca o clasa pentru a fi serializabila XML sunt: clasa trebuie sa fie publica tot membrii serializati trebuie sa fie publici clasa trebuie sa aiba un constructor fara

parametri nu trebuie sa aiba atributul Serializable membri privati sau protected vor fi sariti la

serializare

Page 21: Laborator 05 - Serializare

2111/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Controlul formatului Controlul formatului fisierului XML de iesirefisierului XML de iesire Daca dorim interoperatibilitate cu alte

limbaje de programare uneori este necesara schimbarea formatului in care se va scrie sau citi fisierul XML.

Aceasta schimbare se face prin diferite atribute aplicate membrilor clasei ce va fi serializata/deserializata

Page 22: Laborator 05 - Serializare

2211/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

public class ObiectCumparat { public int productID; public decimal pret; public int cantitate; public decimal total; public ObiectCumparat() { } }

Fisierul XML rezultat dupa serializare va avea urmatorul continut: <?xml version 1.0> <ObiectCumparat> <productID>100</productID> <pret>1000</pret> <cantitate>10</cantitate> <total>1212</total> </ObiectCumparat>

Page 23: Laborator 05 - Serializare

2311/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Controlul formatului Controlul formatului fisierului XML de iesirefisierului XML de iesire Exemple de atribute (pentru o lista completa

vedeti pagina 293 din cartea .NET ADF): XmlAttribute: Membrul va fi serializat ca atribut

XML XmlElement: Membrul va fi serializat ca un element

XML XmlIgnore: Membrul va fi ignorat XmlRoot: Este folosit pentru a specifica optiuni

despre namespace si numele elementului Daca atributele nu sunt suficiente pentru a

obtine formatul dorit, puteti creea propriul serializator XML implementand IXmlSerializable cu metodele ReadXml si WriteXml.

Page 24: Laborator 05 - Serializare

2411/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

ex: [XmlRoot(“ObiectDeCumparat”)

public class ObiectCumparat { [XmlAttribute] public int productID; public decimal pret; public int cantitate; [XmlIgnore] public decimal total; public ObiectCumparat() { } }

<?xml version 1.0> <ObiectDeCumparat productID=“100”> <pret>1000</pret> <cantitate>10</cantitate> </ObiectDeCumparat>

Page 25: Laborator 05 - Serializare

2511/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

XML SchemaXML Schema Atunci cand 2 aplicatii schimba intre ele fisiere

XML, acestea respecta in general o anumita maniera de organizare numita schema. Pentru mai multe info despre Xml schema: http://www.w3.org/XML/Schema

.NET framework contine o aplicatie ce genereaza automat clase dupa o anumita schema (xsd.exe).Cand veti instantia o astfel de clasa fisierul XML generat din ea va respecta schema respectiva. E o metoda mai simpla si typesafe de a parsa si a scrie un document XML care sa respecte un anumit format.

Page 26: Laborator 05 - Serializare

2611/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

XML SchemaXML Schema Pentru a genera o clasa bazata pe o

schema: PAS1: Creati sau copiati schema (fisierul .xsd) PAS2: Deschideti Visual Studio 2005 Command

Prompt PAS3: Rulati comanda: xsd C:\schema\library.xsd /classes

/language:CS PAS4: Folositi clasa nou creata (Schema.cs) in

aplicatia voastra

Page 27: Laborator 05 - Serializare

2711/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Serializare customSerializare custom Serializare custom este procesul prin

care controlati complet mecanismul de serializare si deserializare a unui obiect.

Puteti realiza o interoperatibilitate mai mare si o versionare mai buna folosind serializarea custom.

Page 28: Laborator 05 - Serializare

2811/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum implementam o Cum implementam o serializare custom?serializare custom? Puteti modifica mecanismul .NET de

serializare/deserializare mostenind interfata ISerializable si aplicand atributul Serializable la clasa.

Mostenirea clasei ISerializable inseamna implementarea metodelor GetObjectData si a unui constructor special care va fi folosit la deserializare.

Runtime-ul va apela metoda GetObjectData la serializare si acel constructor la deserializare.

Compilatorul va va avertiza daca nu ati implementat GetObjectData, dar daca nu ati implementat constructorul doar la runtime se va arunca o exceptie la deserializare.

Page 29: Laborator 05 - Serializare

2911/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Cum implementam o Cum implementam o serializare custom?serializare custom? Metoda GetObjectData trebuie sa

completeze un obiect de tip SerializationInfo cu datele pe care doriti sa le serializati din clasa.

Tot ce trebuie sa faceti este sa adaugati valorile de serializat ca perechi nume/valoare (ca la o colectie) folosind metoda AddValue

Metoda AddValue creeaza intern un obiect de tip SerializationEntry

Page 30: Laborator 05 - Serializare

3011/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

[Serializable] class ObiectCumparat : ISerializable { public int productID; public decimal pret; public int cantitate; [NonSerialized] public decimal total; protected ObiectCumparat(SerializationInfo info, StreamingContext context) { this.productID = info.GetInt32(“Product ID”); this.pret = info.GetDecimal(“Pret”); this.cantitate = info.GetInt32(“Cantitate”); this.total = pret*cantitate; }

[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]

public virtual void GetObjectData(SerializationInfo info, StreamingContext context)

{ info.AddValue(“Product ID”,productID); info.AddValue(“Pret”,pret); info.AddValue(“Cantitate”,cantitate); } }

Page 31: Laborator 05 - Serializare

3111/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Evenimente in serializareEvenimente in serializare Atunci cand folositi BinaryFormatter .NET framework poate declansa

anumite evenimente in diferite momente ale procesului de serializare.

Serializare incepe

Serializare incepe [OnSerializing][OnSerializing]

Se face serializarea propriu-zisa

Se face serializarea propriu-zisa

[OnSerialized][OnSerialized]Serializarea s-a terminat

Serializarea s-a terminat

Page 32: Laborator 05 - Serializare

3211/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

Evenimente in Evenimente in deserializaredeserializare

Deserializarea incepe

Deserializarea incepe

[OnDeserializing]

[OnDeserializing]

Deserializarea are loc

Deserializarea are loc

IDeserializationCallback.

OnDeserialization

IDeserializationCallback.

OnDeserialization

[OnDeserialized]

[OnDeserialized]

Deserializarea s-a terminat

Deserializarea s-a terminat

Page 33: Laborator 05 - Serializare

3311/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

EvenimenteEvenimente Pentru a putea raspunde la aceste evenimente

trebuie sa construiti metode ce primesc ca parametru un StreamingContext, au ca atribut tipul de eveniment la care raspund si nu returneaza nimic: ex: [OnDeserializing] void CalculareTotal(StreamingContext sc) { total = pret*cantitate; }

Page 34: Laborator 05 - Serializare

3411/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

StreamingContextStreamingContext Obiectul StreamingContext este folositor atunci

cand doriti o serializare/deserializare diferita in functie de destinatia obiectului.

ex: in general nu e nevoie sa serializati informatii despre procesul in curs pentru ca ele vor fi invechite la deserializare. Totusi daca deserializatorul este chiar procesul in curs aceasta pot fi foarte folositoare

Aceasta informatie este stocata in StreamingContext

Page 35: Laborator 05 - Serializare

3511/26/07L3 .NET ADF - (C) Victor Adrian Prisacariu

StreamingContextStreamingContext StreamingContext are 2 proprietati:

Context: o referinta la un obiect care contine orice informatie dorita de programator legata de informatiile de context

State: un set de biti care indica sursa sau destinatia obiectelor serializate sau deserializate File: sursa sau destinatia este un fisier CrossProcess: sursa sau destinatia este alt proces

pe aceeasi masina CrossMachine: sursa sau destinatia este alt proces

pe alta masina etc.