Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

6. diel - Programujeme pre Windows 8 - Práca so súbormi

V minulej lekcii, Programujeme pre Windows 8 - Zachovanie stavu aplikácie , sme si ukázali akým spôsobom obsluhovať základné Life-Cycle aplikácie. V dnešnom tutoriále si ukážeme niekoľko spôsobov ako čítať a zapisovať dáta do súborov.

Každá aplikácia môže zasahovať iba do vopred určených zložiek. Nemôžeme si vynútiť uloženie nejakého súboru mimo vyhradené zložky bez vedomia užívateľa. Ak budeme chcieť uložiť súbor mimo tieto špeciálne zložky, musíme využiť tzv. Pickery (viď. Nižšie).

Zložky

Ešte raz zložky, kam môžeme zasahovať bez vedomia užívateľa. Zložky sú tiež označované ako Isolated Storage, teda Izolované úložiska.

  • Local Folder - zložka pre súbory (.txt, .xml, obrazové súbory, ...)
  • Roaming Folder - to isté ako Local s tým rozdielom, že táto zložka sa automaticky synchronizuje cez SkyDrive ak ho má používateľ aktívny
  • Temp Folder - Komponent dočasné súbory. Súbory po znovu otvorení aplikácie zmizne.
  • Local Settings - Miesto pre ukladanie rôzneho nastavenia. Je to dátový kontajner. K hodnotám pristupujeme cez Kľúče. Teda Kľúč - Hodnota
  • Roaming Settings - To isté ako Local Settings a opäť synchronizácii cez SkyDrive

Nasledujúce zložky poznáme aj z predošlých systémov a vo WinRT sú označované ako KnownFolders

  • Documents - Zložka určená pre dokumenty
  • Pictures - Komponent obrázky
  • Videos - Komponent video
  • Music - Zložka pre audio

Pozn. Koho by zaujímalo kde sa Local / Roaming zložky nachádzajú tak je to tu: C: \ Users \ Menoužívateľa \ Local \ Packages \ APLIKÁCIE. V packages majú aplikácie meno podľa kľúča. Musíte holt hľadať :)

Uloženie

Poďme si teda niečo uložiť. Uložíme iba .txt súbor vo formáte CSV. Budeme mať databázu používateľov (pozri tento článok http://www.itnetwork.cz/...-souboru-csv od sdraco). Nebudem tu riešiť žiadny návrh aplikácie a objektov. Predpokladám, že máme teda List <Uzivatel> uzivatele. Každý má meno, vek a dátum registrácie. Metóda pre uloženie môže vyzerať nasledovne

public async Task<bool> UlozUzivatele()
{
    //zíká složku Local Folder
    StorageFolder folder = ApplicationData.Current.LocalFolder;

    //vytovří nový soubor asynchronně
    StorageFile file = await folder.CreateFileAsync("uzivatele.txt");

    try
    {
        // načte stream
        Stream stream = await file.OpenStreamForWriteAsync();

        //založí StreamWriter ze stream
        /*
         * Můžeme místo StreamWriter použít i FileIO a metodu jako WriteTextAsync
         * */
        using (StreamWriter writer = new StreamWriter(stream))
        {
            //Zapíšeme uživatele
            foreach (Uzivatel u in uzivatele)
            {
                await writer.WriteLineAsync(string.Format("{0},{1},{2}", u.Jmeno, u.Vek, u.Registrovan.ToString("d.M.y")));
            }
        }
        await stream.FlushAsync();
        return true;
    }
    catch
    {
        return false;
    }
}

Metóda je celkom prostá. Získame zložku, založíme súbor. Zo súboru vytvoríme stream a zapíšeme text. Stream potom uzavrieme. Určite Vás ale zaráža jedna vec. Kľúčové slová ako async a Await už sme raz použili a opäť vás sklamem. Dnes si to ešte nevysvetlíte. Berte to ako kúzelné slovíčko, ktoré nám zaistí asynchrónne beh metód. Celú metódu kvôli používaniu asynchroních metód StreamWriter, Streamu apod musíme označiť ako async! Tým hovoríme, že zakladáme nové vlákno a kdekoľvek je Await, hlavné vlákno s UI beží (reaguje) stále ďalej a v pozadí sa dejú ďalšie výpočty.

Predovšetkým v prostredí Windows 8 aplikácií sa snažte o asynchrónne prístup. Aplikácia neprejde ani certifikáciou ak vám hlavné vlákno s UI zamrzne!

Ak async metóda potrebuje niečo vracať, musí vracať objekt typu Task <T> alebo void.

Ak chceme RoamingFolder, jednoducho načítame Roaming Folder a postup je rovnaký. Načítanie myslím nie je potreba ukazovať. Namiesto StreamWriter by sme použili StreamReader a zo zložky by sme načítali súbor cez GetFileAsync (). Samozrejme miesto StreamWriter / Readeru je možnosť použiť statickú triedu FileIO. Záleží na situáciu a potreby uloženia.

Xml Serializácie

Formát CSV sa hodí naozaj na pár skromných riadkov dát. Oveľa lepšie a prehľadnejšie je XML formát. Máme tu stále možnosť použiť XmlReader / Writer. My si ukážeme jednoduchší a rýchlejší spôsob, ak chceme načítať všetko a vieme čo presne načítame.

Hlavné triedou, ktorá bude potrebné, je XmlSerializer. Trieda ktorá predstavuje dáta musia mať vždy konštruktor bez parametrov a samozrejme pokojne ďalšie s parametrami. Skromná trieda:

public class User
{
   public string Name{get;set;}
   public int Age{get;set;}

   private User()
   {}

  public User(string name,int age)
  {
    this.Name = name;
    this.Age = age;
  }
}

dáta:

List<User> users = new List<User>(){
            new User("Pepa",15),
            new User("Vašek",25),
            new User("Jarmila",15)
        };

A kód pre serializáciu a uloženie

public async Task<bool> Uloz()
{
    try
    {
        StringWriter w = new StringWriter();
        //Načteme složku
        StorageFolder folder = ApplicationData.Current.RoamingFolder;
        //Vytvoříme soubor a v případě existence přemažeme
        StorageFile file = await folder.CreateFileAsync("notes.xml", CreationCollisionOption.ReplaceExisting);
        //Založíme Serializer typu List<User>
        XmlSerializer srl = new XmlSerializer(typeof(List<User>));

        //serializujeme
        srl.Serialize(w, users);

        //zapíšeme přes FileIO
        await FileIO.WriteTextAsync(file, w.ToString());
        // zavřeme StreamWriter
        await w.FlushAsync();

        return true;
    }
    catch
    {
        return false;
    }
}

Opäť myslím, že kód hovorí za všetko :)

Podobne bude načítanie:

public async Task<bool> Nacti()
{
    try
    {
        // načteme složku
        StorageFolder folder = ApplicationData.Current.RoamingFolder;
        //načteme soubor
        StorageFile file  = await folder.GetFileAsync("users.xml");
        //založíme Serializer
        XmlSerializer srl = new XmlSerializer(typeof(List<User>));

        // přeteme text ze souboru (ještě stále XML formát)
        string text = await FileIO.ReadTextAsync(file);

        // založíme XmlReader
        XmlReader r = XmlReader.Create(new StringReader(text));
        //Deserializujeme a přetypujeme
        users = (List<User>)srl.Deserialize(r);

        return true;
    }
    catch
    {
        return false;
    }
}

Vidíme, že práca s XML je veľmi jednoduchá ak nepotrebujeme vytiahnuť určitej časti XML :)

Pickery

Picker je (s trochou nepresnosti) komponenta, ktorá umožňuje užívateľovi uložiť / načítať súbor alebo otvoriť zložku pre čítanie. Je to tiež jediný správny postup ako uložiť dáta mimo určenej zložky. Užívateľ vždy musí vedieť čo sa mu deje na zariadení (PC, tablet, ...).

Picker máme teda 3 typy

  • FileOpenPicker - načíta jeden alebo viac súborov
  • FileSavePicker - uloží jeden alebo viac súborov do nastavenej cesty
  • FolderPicker - umožní otvoriť zložku vnútri aplikácie

U FileOpenPicker a FolderPicker nájdeme jednu dôležitú vlastnosť a tým je FileTypeFilter. Ide o kolekciu List <string> a udáva aký typ súborov môžeme otvoriť / uložiť. Ak chceme všetky typy pridáme do kolekcie hviezdičku () alebo určíme presne typy súborov a to uvedením prípony: .txt, .xtml, .png, ... Podobne u * FileSavePicker nájdeme vlastnosť FileTypeChoices ktorá udáva čo môžeme zvoliť.

Ukážka Picker, ktorý načíta zvolený súbor.

FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".txt");
StorageFile file = await picker.PickSingleFileAsync();
IList<string> result = await FileIO.ReadLinesAsync(file, UnicodeEncoding.Utf8);

Pickery dokážu uložiť aj viac súborov naraz. Určite si pozrite ďalšie nastavenia Picker. Možno je rôzne stylovať :)

Settings

LocalSettings alebo RoamingSettings je špeciálny kontajner, kde môžeme ľahko uchovávať hodnoty podľa kľúča. Je to akýsi trvalý Dictionary. Myslím, že nie je tu čo viac uvádzať.

// uložení
ApplicationData.Current.LocalSettings.Values["name"] = "Zirko";

//načtení
string name = ApplicationData.Current.LocalSettings.Values["name"].ToString();

KnownFolders

Načítanie a ukladanie do KnownFolders je rovnako jednoduché ako ostatné. napríklad Videos

StorageFolder videosFolder = KnownFolders.VideosLibrary;

Capabilities

S KnownFolders as mnohými ďalšími vecami (v budúcnosti si povieme viac) súvisí Package.appxma­nifest. V prvom diele sme si o tomto súbore niečo málo povedali. Pokiaľ využívate KnownFolders, musíte zaškrtnúť tú library, ktorú používate a pridať deklarácie. Avšak už prekračujeme dnešnej náplň článku. Detailnejšie si to popíšeme inokedy.

Dnešný článok bol veľmi teoretický, v budúcej lekcii, Programujeme pre Windows 8 - Vlastné štýly v XAML sa vrhneme na niečo zaujímavejšie :)


 

Predchádzajúci článok
Programujeme pre Windows 8 - Zachovanie stavu aplikácie
Všetky články v sekcii
C # Windows Store aplikácie
Preskočiť článok
(neodporúčame)
Programujeme pre Windows 8 - Vlastné štýly v XAML
Článok pre vás napísal Petr Nymsa
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování v C# a celkově se zajímá o .NET technologie. Působí jako Microsoft Student Partner.
Aktivity