Pobieranie skompresowanych danych na żadanie w Silverlight

Zbyt długie ładowanie aplikacji internetowej potrafi odstraszyć nawet najbardziej zainteresowanych użytkowników, a już  z pewnością nie wpływa pozytywnie na jej odbiór. Przyjemny splash screen to za mało. Aby uruchomić program w Silverlight, strona kliencka musi wcześniej pobrać w całości paczkę xap. Powinniśmy tak zarządzać projektem, aby rozmiar xap był jak najmniejszy. W tym artykule opiszę w jaki sposób odseparować od głównej aplikacji pliki takie jak obrazki czy pliki tekstowe, by pobrać je w postaci skompresowanej zip dopiero w sytuacji, gdy na prawdę tego potrzebujemy.

Co można umieścić poza xap?

Z paczek zip ściąganych na żądanie skorzystałem w grze słownej 7 Letters. Każda paczka dotyczy konkretnego języka, w którym użytkownik może układać słowa. Struktura archiwum jest następująca:

  • słownik w postaci pliku tekstowego o nazwie dict.txt
  • obrazek – flaga kraju / języka o nazwie flag.png

Nie ma potrzeby, aby wszystkie słowniki znalazły się w pliku xap. Zwłaszcza, że słownik domyślny jest dobierany na podstawie ustawień lokalizacyjnych systemu, przez co zmiana języka następuje stosunkowo rzadko. Gdyby jednak użytkownik miał taką ochotę, pobierany jest odpowiedni plik zip i rozpakowywany już po stronie klienta.

W jaki sposób załadować dane w C#

Jest to czynność stosunkowo prosta. Paczkę zip pobierzemy poprzez WebClient, natomiast dane rozpakujemy i załadujemy dzięki StreamResourceInfo.

WebClient wc = new WebClient();
wc.OpenReadCompleted += wc_OpenReadCompleted;
wc.OpenReadAsync(new Uri("fileName.zip", UriKind.Relative));

Plik fileName.zip powinien się znajdować w tym samym katalogu na serwerze co nasza aplikacja. Metoda wc_OpenReadCompleted wywoływana jest tuż po pobraniu danych na dysk użytkownika.

private void wc_OpenReadCompleted(object sender,
                                  OpenReadCompletedEventArgs e)
{
    if (e.Error == null && !e.Cancelled)
    {
        StreamResourceInfo zip =
            new StreamResourceInfo(e.Result, @"application/zip");

        StreamResourceInfo dict =
        Application.GetResourceStream(zip,
            new Uri("dict.txt", UriKind.Relative));

        StreamResourceInfo image =
        Application.GetResourceStream(zip,
            new Uri("flag.png", UriKind.Relative));

        using(var sr = new StreamReader(dict.Stream))
        {
            // wczytujemy zawartość pliku
        }
    }
    else
    {
        // reakcja na błąd
    }
}

Rezultatem działania funkcji OpenReadAsync jest Stream pliku, który znajduje się w e.Result. Zaczynamy od oznaczenia paczki zip jako zasobu (linia 06), później „dobieramy” się do poszczególnych plików (linia 09, 13).

Prawda, że proste?

Share

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Spam protection by WP Captcha-Free