Lekce 4 - Uložení objektů do CSV v C# .NET
V minulé lekci, Práce s textovými soubory v C# .NET, jsme si ukázali zápis do textových souborů i
jejich čtení. Probrali jsme třídy StreamWriter
a
StreamReader
.
V dnešním tutoriálu Soubory v C# .NET vytvoříme plně
objektovou formulářovou aplikaci s databází uživatelů,
která ukládá instance do textových souborů ve formátu
CSV
.
Formát CSV
Nebudeme vymýšlet žádný složitý způsob ukládání dat do textových souborů, protože již jeden osvědčený a standardní existuje. Jmenuje se CSV (jako Comma Separated Values), tedy hodnoty oddělené čárkou, případně středníkem. O CSV jsme se zmínili v lekci Textové řetězce v C# do třetice - Split a Join , dnes je tedy budeme potřebovat.
Založení aplikace
Založme si novou aplikaci typu Windows Forms Application.
Třída Uzivatel
Pojďme se shodnout na tom, jak bude třída uživatele vypadat. Následně
si ukážeme, jak její instance do CSV uložíme. U uživatele budeme evidovat
jeho jméno, věk a datum, kdy byl registrován. Konstruktor bude instanci
inicializovat na základě těchto třech vlastností. Přepíšeme si metodu
ToString()
tak, aby vrátila jméno uživatele. Přidáme si k
němu třídu Uzivatel
:
class Uzivatel { public string Jmeno { get ; private set; } public int Vek { get; private set; } public DateTime Registrovan { get; private set; } public Uzivatel(string jmeno, int vek, DateTime registrovan) { Jmeno = jmeno; Vek = vek; Registrovan = registrovan; } public override string ToString() { return Jmeno; } }
Pojďme si ukázat, jak budou uživatelé ve formátu CSV vypadat. Každý řádek bude reprezentovat jednoho uživatele. Vlastnosti uživatele budou odděleny středníky. Uživatel Pavel Slavík, kterému je 22 let a zaregistroval se 21.3.2000 by vypadal takto:
Pavel Slavík;22;21.3.2000
Na první pohled vidíme, že je soubor relativně jednoduše čitelný, i
když nezasvěcený se může jen domnívat, co je číslo 22
a k
čemu se váže ono datum. V souboru může být samozřejmě více uživatelů,
tedy více řádků.
Třídu uživatele máme, protože však ctíme objektový návrh, vytvoříme si i třídu pro naši databázi.
Třída Databaze
Ta bude obsahovat kolekci uživatelů, tvořenou instancí třídy
List
. Kolekce bude privátní a přidávání uživatelů
(případně jejich mazání, vyhledávání a podobně) bude realizováno
veřejnými metodami. Databáze bude konečně obsahovat metody k načtení CSV
souboru a také k uložení obsahu databáze do souboru. Jméno souboru bude
další privátní atribut databáze. Přidejme si tedy k projektu další
třídu Databaze
a napišme její kostru:
class Databaze { private List<Uzivatel> uzivatele; private string soubor; public Databaze(string soubor) { } public void PridejUzivatele(string jmeno, int vek, DateTime registrovan) { } public Uzivatel[] VratVsechny() { } public void Uloz() { } public void Nacti() { } }
Visual Studio nám metodu VratVsechny()
podtrhne červeně
(protože nevrací hodnotu), ale toho si zatím nebudeme všímat. Pojďme
postupně naimplementovat jednotlivé metody. Začněme konstruktorem.
Konstruktor
V konstruktoru vytvoříme instanci List
a uložíme si cestu k
databázovému souboru:
public Databaze(string soubor) { uzivatele = new List<Uzivatel>(); this.soubor = soubor; }
To bylo velmi jednoduché.
Metoda PridejUzivatele
Na další metodě také není co vymýšlet:
public void PridejUzivatele(string jmeno, int vek, DateTime registrovan) { Uzivatel u = new Uzivatel(jmeno, vek, registrovan); uzivatele.Add(u); }
Metoda VratVsechny()
Metoda VratVsechny()
nám vrátí všechny uživatele. Podobně
můžeme v budoucnu udělat metody pro vyhledávání jen některých
uživatelů. Uživatele navrátíme ve formě pole:
public Uzivatel[] VratVsechny() { return uzivatele.ToArray(); }
Uložení uživatelů do CSV
Nyní se konečně dostáváme k práci s CSV
souborem.
Metoda Uloz()
Začneme using blokem s instancí StreamWriter
. Uvnitř
proiterujeme náš list uživatelů a pro každého uživatele vytvoříme pole
stringů z jeho vlastností. Nestringové vlastnosti musíme na
string
explicitně převést. Pole poté spojíme na dlouhý
string
, ve kterém budou položky oddělené středníky. Spojení
za nás vykoná metoda Join()
. Ta se narozdíl od metody
Split()
volá přímo na třídě String
a jako
parametr (spojovací text) bere také string
, nikoli
char
. Pusťme se do toho:
public void Uloz() { // otevření souboru pro zápis using (StreamWriter sw = new StreamWriter(soubor)) { // projetí uživatelů foreach (Uzivatel u in uzivatele) { // vytvoření pole hodnot string[] hodnoty = { u.Jmeno, u.Vek.ToString(), u.Registrovan.ToShortDateString() }; // vytvoření řádku string radek = String.Join(";", hodnoty); // zápis řádku sw.WriteLine(radek); } // vyprázdnění bufferu sw.Flush(); } }
Kdybychom u data registrace ponechali jen
ToString()
, uložil by se nám i čas, což zde není
příhodné.
Formulář Form1
Pojďme si vše vyzkoušet, přejděme k souboru Formuláře
(Form1.cs
, případně v designeru F7). Zde vytvoříme
privátní atribut databaze
, do kterého v konstruktoru formuláře
uložíme novou instanci naší databáze:
private Databaze databaze; public Form1() { InitializeComponent(); databaze = new Databaze("uzivatele.csv"); }
Na formulář přidejme nové tlačítko, pojmenujme ho
tlacitkoUlozit
a Text
mu nastavme na
"Uložit"
.

V jeho Click handleru (vytvoří se po dvojkliku na tlačítko) přidáme do databáze dva uživatele. Bude to nyní pro vyzkoušení, později bude aplikace vypadat lépe. Dále celou databázi uložíme do souboru:
private void tlacitkoUlozit_Click(object sender, EventArgs e) { databaze.PridejUzivatele("Pavel Slavík", 22, new DateTime(2000, 3, 21)); databaze.PridejUzivatele("Jan Novák", 31, new DateTime(2012, 10, 30)); databaze.Uloz(); }
Aplikaci spustíme a klikneme na tlačítko. Nyní otevřeme (například v
NotePadu) soubor uzivatele.csv
(ve
složka s projektem/bin/debug
) a vidíme, že má následující
obsah:
Pavel Slavík;22;21.3.2000 Jan Novák;31;30.10.2012
Vše tedy funguje, jak má
Načtení uživatelů a dokončení aplikace si necháme na příští lekci, Uložení objektů do CSV v C# .NET - Dokončení.
Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.