IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

Práca s vlastnými súbory v C # 2 - Ukladanie a načítanie zips

V minulom tutoriále o vlastnom formátu súborov sme si predstavili možnosti archívov zips a založili projekt s formulárom pre zadanie zamestnancov. V tomto diele sa naučíme pracovať so zložkou ZIP, ukladať a otvárať súbory vlastného typu.

Načítanie hodnôt do objektu zamestnanca

Teraz musíme do zamestnanca hodnoty z formulára načítať. Presuňme sa späť ku kódu formulára. Všetkým textovým poliam pridajte rovnakú obsluhu udalosti pre KeyUp. V tejto obsluhe dosaďte do zamestnanca hodnoty z textových polí. Metóda zároveň aktualizuje záhlavie okna. KeyUp preto, aby sa udalosť nevyvolávala, keď dosadzujeme do políčka hodnoty z kódu. To bude jedna z ďalších metód.

private void SynchronizacePoli(object sender, KeyEventArgs e)
{
    zamestnanec.Jmeno = txtJmeno.Text;
    zamestnanec.Prijmeni = txtPrijmeni.Text;
    zamestnanec.Email = txtEmail.Text;
    zamestnanec.Telefon = txtTelefon.Text;
    this.Text = txtJmeno.Text + " " + txtPrijmeni.Text;
}

Jediný prvok dtbNarozeni bude využívať udalosti ValueChanged. V obsluhu zamestnanci dosadí svoju hodnotu.

private void dtpNarozeni_ValueChanged(object sender, EventArgs e)
{
    zamestnanec.DatumNarozeni = dtpNarozeni.Value;
}

Teraz budeme potrebovať opak a to nastaviť hodnoty zo zamestnanca do formulára. Toho využijeme keď otvoríme súbor so zamestnancom a budeme ho chcieť načítať. Preto si napíšeme metódu AktualizujFor­mularovaData. Metóda dosadí do všetkých políčok hodnoty zo zamestnancov. Metóda opäť aktualizuje aj záhlavie okna.

private void AktualizujFormularovaData()
{
    txtJmeno.Text = zamestnanec.Jmeno;
    txtPrijmeni.Text = zamestnanec.Prijmeni;
    txtEmail.Text = zamestnanec.Email;
    txtTelefon.Text = zamestnanec.Telefon;
    dtpNarozeni.Value = zamestnanec.DatumNarozeni;
    pcbFoto.Image = zamestnanec.Foto;

    this.Text = txtJmeno.Text + " " + txtPrijmeni.Text;
}

Ukladanie súboru

Zamestnanec bude mať metódu Uloz, ktorá bude prijímať jediný parameter a to cestu k súboru * .zamestnanec. Metóda bude ukladať zamestnanca do zazipované zložky so súbormi foto.jpg a info.xml. Pre info.xml budeme potrebovať metódu, ktorá vygeneruje xml a zapíše xml do archívu. V metóde budeme dosť často pracovať s dátovými prúdmi.

Najprv si vytvoríme dočasný priečinok, kam budeme dáta ukladať. Ukladať dáta priamo do archívu by totiž bolo zbytočne problémové. Využijeme metódy Path.Combine, ktorú skombinujeme s AppData, zložkou pre našu aplikáciu a náhodným názvom. Túto zložku vytvoríme.

string cestaTemp = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
    @"zamestnanci\",
    Path.GetRandomFileName());

Directory.CreateDirectory(cestaTemp);

Pomocou konštrukcia Using vytvoríme dátový prúd pre súbor info.xml v našej dočasnej zložke.

using (FileStream fs = new FileStream(Path.Combine(cestaTemp, "info.xml"), FileMode.Create))
{
    UlozInfo(fs);
}

Tento prúd odovzdáme privátne metóde UlozInfo, ktorá do prúdu zapíše XML.

private void UlozInfo(Stream proud)

Je na vás či XML zapíšete pomocou SAX, DOM alebo budete serializovať. V tomto článku to ani nebudem popisovať detailne. Môj kód exportu vyzerá nasledovne.

XmlDocument doc = new XmlDocument();

XmlElement zamestnanci = doc.CreateElement("Zamestnanci");
XmlElement zamestnanec = doc.CreateElement("Zamestnanec");
zamestnanci.AppendChild(zamestnanec);
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null);
doc.AppendChild(dec);
doc.AppendChild(zamestnanci);

XmlElement Jmeno = doc.CreateElement("Jmeno");
Jmeno.AppendChild(doc.CreateTextNode(this.Jmeno));

XmlElement Prijmeni = doc.CreateElement("Prijmeni");
Prijmeni.AppendChild(doc.CreateTextNode(this.Prijmeni));

XmlElement Email = doc.CreateElement("Email");
Email.AppendChild(doc.CreateTextNode(this.Email));

XmlElement Telefon = doc.CreateElement("Telefon");
Telefon.AppendChild(doc.CreateTextNode(this.Telefon));

XmlElement DatumNarozeni = doc.CreateElement("DatumNarozeni");
DatumNarozeni.AppendChild(doc.CreateTextNode(this.DatumNarozeni.ToShortDateString()));

zamestnanec.AppendChild(Jmeno);
zamestnanec.AppendChild(Prijmeni);
zamestnanec.AppendChild(Email);
zamestnanec.AppendChild(Telefon);
zamestnanec.AppendChild(DatumNarozeni);

doc.Save(proud);

Teraz sa vráťme k metóde Uloz. Vytvoríme ďalší stream, tentoraz pre foto.jpg. Obrázok uložíme jeho metódou Save, ktorá prijíma dátový prúd a výstupný formát. Vďaka výstupného formátu sme schopní obrázok previesť. Hoci treba užívateľ vloží obrázok ako BMP, vždy bude v archíve uložený ako JPG.

using (FileStream fs = new FileStream(Path.Combine(cestaTemp, "foto.jpg"), FileMode.Create))
{
    this.Foto.Save(fs, ImageFormat.Jpeg);
}

Zipovanie zložky v C# .NET

.NET Framework 4.5 a vyššie obsahuje triedy pre prácu so zipováním súborov. Sú v mennom priestore System.IO.Com­pression. Aby ste však tieto menné priestory videli, musíte si pridať k projektu 2 referencie. V Solution Exploreri kliknite pravým tlačidlom na References> Add New Referencie.

Visual Studio pridať referenciu - Súbory v C# .NET

Do vyhľadávacieho políčka napíšte System.IO a označte referencie System.IO.Com­pression a System.IO.Com­pression.File­System.

Pridať refernce System.IO.Compression - Súbory v C# .NET

Dialóg potvrďte. Do Using si pridajte odkazy na tieto knižnice.

Trieda ZipFile má statickú metódu CreateFromDirec­tory, ktorá prijíma dva parametre. Prvý parameter je cesta k priečinku, ktorá má byť zazipované a druhý je výsledný súbor. Tento súbor nemusí mať nutne príponu zips a toho využijeme. Viacmenej však iba metóde dosadíme cesty.

ZipFile.CreateFromDirectory(cestaTemp, soubor);

Vráťme sa do formulára. Vytvorte udalosť Click na objekte btnUlozit. Opäť budeme vytvárať dialóg. Pretože filter pre príponu zamestnancov použijeme 2 × (otváranie a ukladanie), dáme ju triede Zamestnanec ako statický člen.

public static string filter = "Soubor zaměstnance (*.zamestnanec)|*.zamestnanec";

Dialógu dosadíme predvolený názov súboru, ktorý bude vychádzať z mena a priezviska zamestnanca. Dialóg otvoríme. Ak vráti OK, zamestnancov uložíme.

private void btnUlozit_Click(object sender, EventArgs e)
{
    SaveFileDialog dialog = new SaveFileDialog();
    dialog.Filter = Zamestnanec.filter;
    dialog.FileName = zamestnanec.Jmeno + " " + zamestnanec.Prijmeni;
    if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
        zamestnanec.Uloz(dialog.FileName);
    }
}

Aplikáciu si spustite. Vyberte nejakú fotku, vyplňte textové polia a nejaké dátum. Skúste zamestnanca uložiť. Skúste zmeniť jeho príponu na zips a pozrite sa dovnútra. Bude tam fotka a súbor info.xml.

Ukážka vyexportovaného zamestnanca - Súbory v C# .NET

Otvárania súborov v programe

Otvárania súboru budeme riešiť v druhom preťaženom konstruktoru. Do konstruktoru nám v parametri bude odovzdaná cesta k súboru so zamestnancom. Z tohto súboru potrebuje získať dátový prúd, ten odovzdáme v konštrukcii Using konstruktoru triedy ZipArchive.

public Zamestnanec(string soubor)
{
    using (FileStream fs = new FileStream(soubor, FileMode.Open))
    {
        using (ZipArchive zip = new ZipArchive(fs))
        {

        }
    }

}

ZipArchive má metódu GetEntry, ktorá vráti ZipArchiveEntry. Ten obsahuje súbor uložený v archíve. ZipArchiveEntry má potom metódu Open, ktorá vracia dátový prúd k súboru. Info.xml budeme načítavať v metóde NactiInfo, ktoré opäť odovzdáme dátový prúd a tá spracuje XML.

ZipArchiveEntry info = zip.GetEntry("info.xml");
NactiInfo(info.Open());

NactiInfo môžete zase napísať viacerými spôsobmi, ja som použil DOM. Môj kód vyzerá nasledovne.

private void NactiInfo(Stream proud)
{
    XmlDocument doc = new XmlDocument();
    using (XmlReader r = XmlReader.Create(proud))
    {
        doc.Load(r);
        this.Jmeno = doc.GetElementsByTagName("Jmeno")[0].FirstChild.Value;
        this.Prijmeni = doc.GetElementsByTagName("Prijmeni")[0].FirstChild.Value;
        this.Email = doc.GetElementsByTagName("Email")[0].FirstChild.Value;
        this.Telefon = doc.GetElementsByTagName("Telefon")[0].FirstChild.Value;
        this.DatumNarozeni = DateTime.Parse(doc.GetElementsByTagName("DatumNarozeni")[0].FirstChild.Value);
    }
}

Fotku načítame podobne, z dátového prúdu obrázok dostaneme pomocou statickej metódy Image.FromStream.

ZipArchiveEntry foto = zip.GetEntry("foto.jpg");
this.Foto = Image.FromStream(foto.Open());

Vráťme sa k formuláru a vytvorte obsluhu udalosti Click pre tlačidlo otvoriť. Opäť vytvoríme dialóg a opäť mu načítame filter. Otvoríme ho a porovnáme návratovú hodnotu s OK. Ak používateľ súbor vyberie, vytvoríme nového zamestnanca a v konstruktoru mu odovzdáme cestu k súboru. Nakoniec aktualizujeme dáta na formulári, aby sa zmeny zo zamestnanca prejavili aj na formulári. Celá metóda by mohla vyzerať nasledovne.

private void btnNacist_Click(object sender, EventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();
    dialog.Filter = Zamestnanec.filter ;
    if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
        zamestnanec = new Zamestnanec(dialog.FileName);
        AktualizujFormularovaData();
    }
}

Teraz je aplikácia hotová, môžete vyskúšať.

načítanie zamestnanca - Súbory v C# .NET

Aplikáciu poriadne vyskúšajte, nabudúce sa pozrieme na možné vylepšenia. Ošetríme chyby a vyšperkuje súbory v prieskumníkovi Windows. V kóde pod článkom máte na testovanie priloženého i plne validného zamestnanca Jána Nováka.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 259x (67.65 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Všetky články v sekcii
Súbory v C# .NET
Článok pre vás napísal Michal Žůrek - misaz
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.
Aktivity