Na czym też polega owa serializacja? Otóż platforma .NET dostarcza nam ciekawego mechanizmu zwanego atrybutami. Nadanie atrybutu jakiejś klasie, daje możliwość wyczyniania z nią różnych rzeczy przez inne klasy. A jak to ma się do tematu? Istnieje atrybut [Serializable], który dołączony do klasy powoduje iż istnieje możliwość jej serializacji w dwóch typach - do pliku XML oraz do strumienia binarnego. A sama serializacja powoduje zapisanie wszystkich danych (stanu) przechowywanych w klasie poddanej temu zabiegowi. Co ciekawsze, jeżeli jakaś klasa załóżmy nazywająca się Samochod która sama posiada atrybut Serializable, zawiera w sobie listę obiektów klasy Czesc która również posiada ten atrybut, to przy serializacji klasy Samochod zostaną automatycznie zserializowane wszystkie wystąpienia klasy Czesc. Ale przejdmy do tego jak działa ten mechanizm.
Utwórzmy zatem klasę, którą można będzie bezkarnie zserializować...
[Serializable]
class MojaKlasa {
int a;
string b;
float c;
//prosty konstruktor który ustawia stan klasy
MojaKlasa(int pa, string pb, float pc) {
this.a = pa;
this.b = pb;
this.c = pc;
}
}
Do zserializowania obiektu potrzebujemy innego obiektu klasy BinaryFormatter znajdującego się w przestrzeni nazw System.Serialization.Formatters.Binary . Musimy również dołączyć przestrzeń nazw System.Serialization aby można było nadać atrybut. W kodzie import tych przestrzeni wygląda następująco:
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
Ponieważ jednak BinaryFormatter jako parametr serializacji przyjmuje strumień, musimy zdecydować się w jakim strumieniu umieścimy nasz zserializowany obiekt. Najprostszym sposobem jest umieścić nasz obiekt w pliku, więc utwórzmy strumień plikowy. Klasy potrzebne do jego utworzenia znajdują się w przestrzeni nazw System.IO. Deklaracja takiego strumienia wygląda następująco:
FileStream fs = new FileStream(@"mojplik.bin", FileMode.Create);
Powyższa linia kodu mówi tyle co: Utwórz strumień plikowy, który będzie przypisany do pliku "mojplik.bin" w trybie tworzenia (czyli jeżeli istnieje taki plik to go nadpisz).
Mamy już przygotowany strumień, teraz czas zabrać się za serializację.
BinaryFormatter bf = new BinaryFormatter();
Utworzyliśmy nasz formater, ale jak teraz zserializować klasę? Po pierwsze utwórzmy jej obiekt:
MojaKlasa mk = new MojaKlasa(1,"Jakiś napis",3.14f);
Mamy już świeży obiekt naszej klasy, na dodatek wypełniony danymi. Przystąpmy zatem do serializacji:
bf.Serialize(fs,mk);
fs.Close();
Tym samym zserializowaliśmy binarnie naszą klasę. Druga linia powoduje zamknięcie strumienia plikowego, co skutkuje fizycznym zapisem pliku na dysk.
I oto cała serializacja. Dość proste. W najbliższym czasie rozbudujemy trochę ten przykład, tak żeby dodatkowo zaszyfrować i spakować zserializowany obiekt.
Mam nadzieję że ten post będzie przydatny.
Kolego, bardzo pomógł mi Twój art i dziekuje Ci bardzo za niego! Natrafiłem niestety na barierę, która próbuje przeskoczyć od kilku godzin, nie wiem jak wykonać deserializacje i przypisać te zserializowane zmienne do zmiennych w strukturze (w innej formie), otóż deserializacja przebiega pomyslnie ale dostaje objekt klasy zserializowanej i nie wiem jak wydobyc z niej te zmienne :/
OdpowiedzUsuńTen komentarz został usunięty przez autora.
OdpowiedzUsuńOskar: Mi udało się to zrobić w następujący sposób - pod fs.Close() dodaj następujący kod (zmieniając "type" oraz "path" na docelowy typ i ścieżkę):
OdpowiedzUsuńfs = new FileStream(path, FileMode.Open);
type instance = (type)bf.Deserialize(fs);
Czy wiecie może jak serializować tylko zmienne?
OdpowiedzUsuń