CodeGym /Kursy /C# SELF /Zapoznanie z serializacją

Zapoznanie z serializacją

C# SELF
Poziom 43 , Lekcja 0
Dostępny

1. Wprowadzenie

Wyobraź sobie, że twój obiekt w programie to taki złożony, ładny konstruktor LEGO. Składa się z wielu elementów, każdy na swoim miejscu, i wszystko razem tworzy jedną całość. Dopóki konstruktor stoi na twoim biurku (w pamięci komputera), jest w porządku. Ale co, jeśli musisz przewieźć go do znajomego (przesłać przez sieć), albo po prostu schować do pudełka do następnego razu (zapisać na dysku)? Nie możesz po prostu wziąć i położyć go na płask w pudełku! Zniszczy się!

Właśnie tym — ostrożnym rozłożeniem obiektu na części dla bezpiecznego przechowywania lub przesyłu — zajmuje się serializacja. To proces przekształcania twojego obiektu z jego "żywego" stanu w pamięci do sekwencji bajtów (lub reprezentacji tekstowej), którą można zapisać do pliku, przesłać przez sieć lub umieścić w schowku. W istocie to jak staranne rozłożenie twojego LEGO na elementy, zapakowanie ich w woreczki, podpisanie i zapakowanie do pudełka do transportu lub przechowywania.

flowchart LR
    ObjectInMemory(Obiekt w pamięci)
    Serialize[SERIALIZACJA]
    BytesOrText[Bajty / Plik tekstowy / JSON / XML]
    Deserialize[DESERIALIZACJA]
    ObjectAgain(Obiekt z powrotem w pamięci)

    ObjectInMemory -->|serialize| Serialize
    Serialize --> BytesOrText
    BytesOrText -->|deserialize| Deserialize
    Deserialize --> ObjectAgain

I oczywiście, jeśli coś zapakowaliśmy, musimy umieć to rozpakować! Proces odwrotny nazywa się deserializacją. To kiedy bierzesz pudełko z woreczkami elementów LEGO, wysypujesz je, a potem, zgodnie z instrukcją (albo po prostu pamiętając, jak to było złożone), odtwarzasz obiekt w pamięci w dokładnie takim samym stanie, jak był przed zapakowaniem. Taka magia!

Termin "serializacja" dosłownie oznacza "przedstawienie sekwencyjne". Bierzemy złożoną, możliwie rozproszoną w pamięci strukturę (obiekt może wskazywać na inne obiekty, kolekcje itp., tworząc cały "graf obiektów") i zamieniamy ją na liniową, sekwencyjną formę, którą łatwo zapisać lub przesłać.

2. Dlaczego nie wystarczy po prostu File.WriteAllText?

Świetne pytanie! Gdyby wszystkie dane były prostymi stringami lub liczbami, obylibyśmy się bez serializacji. Ale w realnym świecie aplikacje operują złożonymi modelami: klienci, zamówienia, produkty, studenci, bohaterowie, poziomy. Wszystko to są obiekty w pamięci. I dlatego serializacja to twój najlepszy przyjaciel:

Zapisywanie stanu aplikacji

Wyobraź sobie, że piszesz edytor tekstu. Użytkownik wpisuje tekst, zmienia fonty, wstawia obrazki. Wszystkie te dane (tekst, ustawienia, pozycja kursora) to w istocie obiekty w twoim programie. Kiedy użytkownik klika "Zapisz", chcesz, żeby przy następnym uruchomieniu programu zobaczył wszystko dokładnie tak, jak zostawił. Serializacja pozwala "zamrozić" wszystkie potrzebne obiekty i zapisać je na dysku, a potem "odmrozić" przy ładowaniu. To jak funkcja "zapisz grę" w grach wideo. Na pewno nie chcesz przechodzić tego poziomu od nowa, jeśli wyłączą prąd?

Wymiana danych między aplikacjami

Twój program w C# komunikuje się z webserwisem, który może być napisany w Pythonie. Albo twoja aplikacja mobilna (np. na Xamarin lub MAUI) komunikuje się z serwerem na .NET. Te programy nie dzielą pamięci. Aby wymienić dane, potrzebują wspólnego, zrozumiałego formatu. Serializacja przekształca obiekty do tego wspólnego formatu (na przykład JSON lub XML), który można przesłać przez sieć. Po drugiej stronie odbiorca deserializuje te dane z powrotem do swoich obiektów, zrozumiałych dla ich języka programowania. Bez serializacji musiałbyś ręcznie "rozpakowywać" każdy kawałek danych i składać go z powrotem. To byłoby długo, nudne i bardzo podatne na błędy!

Wyobraź sobie, że wysyłasz paczkę do innego kraju. Nie możesz po prostu wysłać rzeczy "jak leci"; musisz zapakować je w kontener (serializacja) według międzynarodowych standardów. Po drugiej stronie odbiorca będzie mógł otworzyć ten kontener i wyjąć swoje rzeczy (deserializacja).

Konfiguracja aplikacji

Często aplikacje mają mnóstwo ustawień: rozmiar okna, ścieżka do plików, ostatnio otwarte dokumenty, schemat kolorów. Trzymać każde ustawienie w osobnej zmiennej, a potem ręcznie zapisywać je do pliku konfiguracyjnego (np. .ini lub .txt) — to nieefektywne i niewygodne. Znacznie prościej zdefiniować klasę UstawieniaAplikacji, gdzie każde ustawienie to właściwość, a potem po prostu zserializować cały obiekt ustawień do pliku. Przy starcie programu — zdeserializować. Prosto i ładnie!

Cache'owanie danych

Czasem pobranie danych (np. z bazy danych lub zdalnego serwera) zajmuje dużo czasu. Aby nie żądać ich za każdym razem, można pobrać raz, zserializować i zapisać do cache (na dysk lub do specjalnego magazynu). Przy następnym żądaniu najpierw sprawdzamy cache, i jeśli dane tam są, po prostu deserializujemy je. To znacząco przyspiesza działanie aplikacji i zmniejsza obciążenie zewnętrznych źródeł danych.

3. Główna idea: zapisywanie "stanu"

Najważniejsza koncepcja w serializacji to zapisywanie stanu. Obiekt to w istocie suma swoich pól i ich wartości w danym momencie czasu. Serializacja "robi zdjęcie" tego stanu. Kiedy deserializujemy obiekt, nie tylko tworzymy nowy pusty obiekt, ale odtwarzamy go ze wszystkimi wartościami pól, które miał w momencie serializacji.

To nie jest zwykłe kopiowanie danych. To głębokie skopiowanie struktury i wartości, łącznie z referencjami do innych obiektów, jeśli serializer potrafi z nimi pracować. Niektóre serializery mogą nawet zapisać informację o typie obiektu, co pozwala zdeserializować go z powrotem do właściwej klasy, nawet jeśli w momencie deserializacji nie znamy dokładnego typu wcześniej.

Klasyczny przykład: serializacja zwierzaków

Kontynuujemy rozwój naszej aplikacji "Encyklopedia zwierzaków". Załóżmy, że mamy taką klasę:

public class Pet
{
    public string Name { get; set; }
    public string Type { get; set; } // Například: "Kot", "Pies"
    public int Age { get; set; }
}

Chcemy:

  • Wypełnić kolekcję takich obiektów w pamięci,
  • Zapisać ją do pliku,
  • A później odtworzyć (np. po restarcie programu).

Schematycznie wygląda to tak:


Kolekcja List<Pet>
    ↓ serializacja
    Plik (JSON, XML, bajty)
    ↓ deserializacja
Kolekcja List<Pet> (z powrotem w pamięci!)

4. Jakie są formaty serializacji

Tak jak w świecie transportu, gdzie są różne rodzaje kontenerów (kartonowe pudełka, skrzynie drewniane, metalowe kontenery), tak w programowaniu istnieją różne formaty serializacji. Każdy z nich ma swoje cechy, zalety i wady.

Na razie nie będziemy się w nie zagłębiać, ale zapamiętaj kilka nazw, żeby rozumieć, o czym będziemy mówić na kolejnych wykładach:

  • JSON (JavaScript Object Notation): Obecnie to chyba najpopularniejszy format. Jest tekstowy, względnie czytelny dla człowieka i szeroko używany do wymiany danych w sieci. Wygląda jak pary "klucz-wartość" zamknięte w klamrach. W zasadzie to zwykły tekst, ale zorganizowany tak, że programom łatwo go parsować.
  • XML (Extensible Markup Language): Starszy, ale wciąż powszechny tekstowy format. Opiera się na tagach, jak HTML, i ma ścisłą strukturę. Często używany do plików konfiguracyjnych i wymiany danych w systemach korporacyjnych. Też czytelny, ale często dość rozwlekły.
  • Formaty binarne: Te formaty zapisują dane nie jako tekst, lecz bezpośrednio jako bajty, tak jak są w pamięci. Zwykle są bardziej kompaktowe i szybsze do serializacji/deserializacji, ale całkowicie nieczytelne dla człowieka. Używa się ich tam, gdzie liczy się maksymalna wydajność lub minimalny rozmiar pliku, np. do zapisu danych gry lub przesyłania dużych wolumenów informacji między komponentami własnego systemu.

Wybór formatu zależy od zadania: czy człowiek ma mieć łatwość odczytu danych? Czy ważna jest szybkość i rozmiar? Na jakie platformy przesyłasz dane? Do wymiany między różnymi systemami JSON i XML często są preferowane ze względu na uniwersalność. Do przechowywania danych wewnątrz tej samej aplikacji formaty binarne mogą być szybsze i bardziej efektywne.

Jak widzisz, serializacja to potężne narzędzie leżące u podstaw wielu nowoczesnych aplikacji. Pozwala naszym programom "pamiętać" dane między uruchomieniami, komunikować się między sobą i efektywnie zarządzać złożonymi informacjami. W kolejnych wykładach nie będziemy już tylko opowiadać o "magii", ale nauczymy się, jak ją stosować, używając bibliotek .NET! Przygotuj się, będzie ciekawie!

2
Zadanie
C# SELF, poziom 43, lekcja 0
Niedostępne
Konwersja kodowania pliku
Konwersja kodowania pliku
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION