Zdravím,
rád bych napsal WinForm aplikaci, která by vytvořila a zpracovávala údaje cca 20 lidí. Jsem začátečník, v knize jsem se dozvěděl, jak ukládat data jednoduše pomocí SaveFileDialogu ve VS.
Ovšem to mi v mém případě přijde zdlouhavé, o každém člověku potřebuji uložit pouze pár řádků dat. Proto nechci pro každého vytvářet nový soubor např v .txt.
Potřeboval bych buď poradit způsob, jak ukládat všechna data do jednoho souboru .txt, aby se nepřepisovala každým novým člověkem, nebo nejlépe tak, aby uživatel nemusel ani manipulovat s tím ukládacím dialogem a samozřejmě z toho souboru zase data načítat.
Bohužel ještě neovládám databáze, takže do těch bych se nerad pouštěl (jestli by vůbec mělo cenu s němi v tomhle případě něco podnikat:-/). Mimochodem gůglil jsem, ale nenašel nic v češtině o Lokálních databazích ve VS. Kdyby měl někdo nějaký link, z kterého bych se dozvěděl aspoň základy, nezlobil bych se :).
Předem děkuji za rady
Fórum › .NET
C# : Ukládání dat ve WForms
SaveFileDialog služi len k tomu, aby si dostal cestu, kam je vhodne zapisovať súbor. To ako to využiješ je na tebe. Do jedneho .txt suboru môžeš zapísať čo len potrebuješ, len si musiš vytvoriť metody, ktore ho uspešne rozložia na dáta, ktoré ťa zaujímajú. Pre inšpiraciu dodam, ak chceš napríklad pridať človeka do zoznamu, načítaš si celý súbor do dátových štruktúr, ktoré sú schopné pracovať rýchlo a flexibilne. Do nich pridáš údaje človeka a celý súbor zapíšeš znovu, tak sa to robí. Ďalší spôsob je využiť xml, čo sa vo svojej podstate zhoduje s .txt, ale má to určitú syntax, ktorá sa bežne používa. Výhoda je v existujúcich nástrojoch pre pohodlné získavanie dát.
Nejaké informácie sú tu:
http://casopis.programator.cz/index.php?rubrika=15
Práce s XML v C#
Hlavne premysli poriadne celý návrh programu.
Veľa šťastia !
To mephi : Děkuji. Přečtu si něco o tom XML, doufám že to v těch článcích je trošku pro amatéry :) .
Přesto by mě zajímal i ten první způsob, jak to "načíst do datových struktur"? Nejsem si úplně jistý - jsou to ty struktury, které jsou v podstatě obdobami tříd, ale hodnotového typu? Ještě jsem s nimi nikdy nepracoval, zkusím teda taky něco vygooglit.
Každopádně děkuju. S pozdravem Hoffik
ak je v .txt súbore "123" a ty načítaš jeho hodnotu do premennej, napr. int. To je pre mňa načítanie do dátovych štruktúr. Nehľadaj za tým nič zložité. jednoducho "dostať hodnoty zo súboru do programu".
Samozrejme, ak riešiš viac položiek pre jeden záznam a takých záznamov môžeš mať viac, je lepšie a prehľadnejšie to udržiavať v zložitejších štruktúrach (teraz nehovorim o struct, ale všeobecnejšie).
Pre ešte lepšiu predstavu uvediem:
zaznam.txt
Jan Novak 41 50000 Praha
Petra Nová 37 34000 Brno
takto napríklad môže vyzerať súbor. Načítaš zaradom meno vek plat mesto
Osobne by som vytvoril triedu (class) osoba, ktorá by mala členy, do ktorých sa uložia údaje o jednej osobe.
potom vytvoril pole takých osôb a načítaval.
príklad pre xml:
<root>
<osoba name="Jan Novak" vek="41" plat="50000" mesto="Praha"/>
<osoba name="Petra Nová" vek="38" plat="34000" mesto="Brno"/>
</root>
To mephi : No právě mám malinko problém s tím vytvořením třídy "osoba". Myslíš tím, že pak mám vytvořit ještě další třídy, jako "vek, plat, mesto.."? A jak mám do těch tříd ukládat údaje o JEDNÉ osobě? Jako datové složky? :/
Sorry, jak vidíš tak sem si vzal asi velké sousto:-( . Každopádně to XML určitě také vyřeší můj problém, prokousávám se tím seriálem, netušil sem že něco takového je. Díky.
Hoffik
skus tuhle třídu:
class osoba
{
public int vek { get; set; }
public int plat { get; set; }
public string mesto { get; set; }
public osoba()
{
this.vek = 18;
this.plat = 1500;
this.mesto = "New York";
}
public osoba(int vek,int plat,string mesto)
{
this.vek = vek;
this.plat = plat;
this.mesto = mesto;
}
}
no a vytvořil bych si nějaký pole objektů a do toho bych si ty data ulozil. Pak bych provedl úpravy a zase z pole ulozit do souboru.
To SeraphCZ :
Moc díky za rady. Ale...
Ehm.. Ta první metoda je konstruktor, je to tak? A ty hodnoty má přiřazené, jen aby ten objekt neměl defaultně prázdné hodnoty, nebo je jiný důvod?
A za další - mohl by si mi prosím předvést malou ukázku pole objektů? A jak do nich uložit data která zadá uživatel např. do textBoxu?
Mockrát děkuji, Hoffik
Jasný to jsem tam dal aby tam proste neco bylo, ten prázdnej konstruktor by tam vlastně ani nemusel být. To pole objektů by vypadalo takhle
osoba[] DatabazeOsob = new osoba[20];
//potom plníš třeba takhle
DatabazeOsob[0] = new osoba(18,15000,"Horní Dolní");
DatabazeOsob[1] = new osoba(35,25000,"Ostrava");
//atd.
samozdrejme jdou použít pokročilejší konstrukce než obyčejný pole (Myslím že se tomu říká kontejnery (ArrayList, Vector (ten mozna v C# není hrozně se mi míchá Java a C#. Mají například tu výhodu že nemusíš předem určit velikost pole. Stačí trochu pogooglit.
To SeraphCZ :
Jo super :) . A jak si říkal "kontejnery" tak tomu se říká kolekce, ale radši zůstanu u těch polí. Nejspíš budu taky nastupovat na VŠ, kde se probírá Java, takže se toho trošku děsím (i když v C# se mi nemá moc co plíst, když skoro nic neumím:) ). Díky za pomoc.
Zdar
To SeraphCZ : Ahoj. Pořád s tím mám problémy. Díky za ochotu, ale..
Jseš si jistý tím plněním pole? Podle tvého příkladu mi to píše :
Error 1 Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
(a je podtrženo to [0], [1] atd..)
Dále se tomu nelíbí znak přiřazení "=", taky podtržen s chybou:
Error 2 Invalid token '=' in class, struct, or interface member declaration
A v těch kulatých závorkách to píše že "Type expected".
:(
Tady je ještě ta třída osoba, předpokládám, že problémy plynou také z ní...
class osoba
{
public string mesto { get; set; }
public string jmeno { get; set; }
public osoba(string mesto, string jmeno)
{
this.mesto = mesto;
this.jmeno = jmeno;
}
}
To liborb : Kéž by :) ... Zkusil jsem to takto:
class osoba
{
public string mesto { get; set; }
public string jmeno { get; set; }
public osoba(string mesto, string jmeno)
{
this.mesto = mesto;
this.jmeno = jmeno;
}
osoba[] DatabazeOsob = new osoba[3];
DatabazeOsob[0] = new osoba("praha","jarda");
DatabazeOsob[1] = new osoba("brno","pepik");
DatabazeOsob[2] = new osoba("ostrava","karel");
}
Nelíbí se tomu číslo pořadí těch prvků (0,1,2), rovnítka a názvy měst..
I kdyby se mi však toto podařilo, nevím, jak bych to pole naplnil pomocí textBoxů a uložil do např. .txt abych z něj zase mohl načítat ( třeba zase po zadání příslušného jména do jiného textBoxu). Doufám, že je to nějak jednoduše možné.
Předem dík za jakoukoliv radu.. a děkuji za trpělivost ;)
Takhle to nemůžeš dělat. Když chceš s tou databází dělat nějaké operace, tak z toho rovnou udělej třídu, například:
class databazeOsob
{
private osoba[] databaze;
private int index;
public databazeOsob()
{
databaze = new osoba[20];
index = 0;
}
public void vlozOsobu(string mesto, string jmeno)
{
databaze[index] = new osoba(mesto, jmeno);
index++;
}
}
no a pak to někde použij:
static void Main(string[] args)
{
databazeOsob db = new databazeOsob();
db.vlozOsobu("praha", "josef");
}
A sazmozřejmě si pak přiděláš funkce na načtení ze souboru, na uložení do souboru, na procházení a editaci jednotlivých položek ....
A při 21 osobách ti to spadne :)
Zkus radši generický List...
class databazeOsob {
private List<osoba> databaze;
public databazeOsob() {
databaze = new List<osoba>
}
public void vlozOsobu(string mesto, string jmeno) {
databaze.add(new osoba(mesto, jmeno));
}
public osoba ziskejOsobuDleJmena(string jmeno){
foreach(osoba x in this.databaze){
if(x.jmeno.equals(jmeno)){
return x;
}
}
return null;
}
}
Dále bych chtěl upozornit, že dobrým zvykem je začínat jména tříd velkým písmenem (takže ne osoba ale Osoba, ne databaseOsob ale DatabaseOsob atd) stejně tak public metody, proměnné a vlastnosti :) Narozdíl od Javy, ale i tam se class začínají velkým písmenem...
A pak to ukládání... No, XML by bylo nejlepší, jenomže pro začátečníka nic moc všechny ty childs, parent, sibling etc...
Proč ne prostě .txt s odřádkováním jako delimeter a tak? :)
using System;
using System.Collections.Generic;
using System.IO;
class databazeOsob {
private List<osoba> databaze;
private string mujSoubor = Environment.CurrentDirectory+@"\db.txt";
private bool isSynchro = false;
public databazeOsob() {
databaze = new List<osoba>
}
public void vlozOsobu(string mesto, string jmeno) {
databaze.add(new osoba(mesto, jmeno));
}
public osoba ziskejOsobuDleJmena(string jmeno){
foreach(osoba x in this.databaze){
if(x.jmeno.equals(jmeno)){
return x;
}
}
return null;
}
public void Save(){
TextWriter tw = null;
if(this.isSynchro){
tw = new StreamWriter(this.mujSoubor, false);
} else {
tw = new StreamWriter(this.mujSoubor, true);// to true je tam pro append k stavajicimu textu (jinak by se prepsal stary
}
foreach(osoba x in this.databaze){
tw.WriteLine(x.jmeno);
tw.WriteLine(x.mesto);
tw.WriteLine();
}
tw.Close();
}
public void Load(){
this.isSynchro = true;
StreamReader r = new StreamReader(this.mujSoubor);
string line = String.Empty;
while((line = r.ReadLine()) != null) {
string jmeno = line, mesto = r.ReadLine();
r.ReadLine(); //posun čtecí hlavičky o tu jednu mezeru kterou jsme si oddělili zaznamy v this.Save()
vlozOsobu(mesto, jmeno);
}
r.Close();
}
}
Pisu to z hlavy, takze mozna je tam nejaky preklep... Krasny den :)
splite napsal: public databazeOsob() {
databaze = new List<osoba>
}
[/Citace]
Oj, samozřejmě že hned překlep... tady má samozřejmě být:
databaze = new List<osoba>();
a ještě bych to vylepšil touhle vlastností:
public osoba this[int index]{
get {
if(this.database.Count < index){
return null;
}
return this.databaze[index];
}
}
aby jsi potom někde v kódu mohl používat parádní:
databazeOsob db = new databazeOsob();
db.Load();
for(int i = 0; db[i] != null; i++){
osoba obcanKane = db[i];
blablabla;
}
Díky pánové. Do XML, jak jsem zjistil, ještě opravdu nemá cenu investovat moc energie. Potřeboval bych nějaké jednodušší řešení.
O generických listech jsem slyšel poprvé, ale když jsem si prošel kód tak to vypadá velmi "elegantně". Jenže abych to rozchodil, musel bych v podstatě jen kopírovat z příspěvku splita, což by mi moc pomohlo ale v rámci samostudia zkusím liborbovu metodu :) ..
Děkuji za ochotu!
To liborb : Prosímtě, šla by ještě napsat malá ukázka metody pro uložení těch hodnot? Načtení si snad odvodím.
Doufám že si rozumíme, doufal jsem v to, že aplikace "uloží" jméno, které uživatel zadá do např. textBoxu. Uloží se do .txt a pak znovuvložením, například jména, by se načetla např. adresa k tomu jménu.
A jestli jsem to pochopil, tak uživatel může zadat jen tolik "kontaktů" kolik je velikost toho pole, nelze to nějak "dynamicky zvětšovat"?
To splite - neměl bys prosím nějáky link, kde bych se dozvědel více o těch generických listech?
Předem dík
Když se to učíš, tak to vezmu trochu ze široka, snad tě neodradím :smile1: .
Objektový přístup má mnoho výhod a jednou z nich je zapouzdřenost, tj. ty "nevidíš" vnitřek objektu, ale pouze rozhraní, které s ním pracuje. To dává tvůrci objektu i takovou možnost, že zcela změní datovou strukturu, která ukládá stav objektu a zvenčí se nic nepozná - rozhraní zůstane stejné.
Tím chci říct, že použití pole nebo listu závisí zcela na konkrétním použití. Určitě nebudeš bajty z bitmpay ukládat do listu, ale můžeš. Důležité pro rozhodnutí jsou požadavky, které na to máš. Pokud znáš alespoň přibližně maximální počet položek ve tvé databázi, tak ti nic nebrání udělat to přes pole. Pokud maximum neznáš, tak je pole nevhodné. V takové případě je lepší list. List má obecně "nevýhodu" v rychlosti. Uvozovky jsem použil z toho důvodu, že .NET si programátor nevybere kvůli rychlosti programu, ale kvůli rychlosti vývoje. V tomto případě je pole "dýchavičné" :smile1: . A ano, do pole se vejde jen tolik hodnot, jak je velké. Dynamicky zvětšovat ho lze (už jenom způsobem, že si vytvoříš nové - větší - pole a to staré do něj překopíruješ), ale právě vzhledem k tomuto se používá list, kde paměť jen přidáváš a nikoliv i "zahazuješ". Můžeš si ale velikost nastavit třeba v konstruktoru.
Jenže je ještě druhý apekt a to ten, že není od věci znát pozadí použitého způsobu. Můžeš dané problematice rozumět a pak vhodně zvolit odpovídající datovou strukturu. Nebo můžeš umět "jen" používat generické listy, ale pak se ti může stát, že data bitmapy budeš ukládat zase do listu a .... Tím chci říct, že není nic špatného na tom, vědět nejenom jak se to používá, ale i to proč se to používá.
Ukládání do souboru resp. nahrávání ze souboru budeš dělat pouze jednou. Při startu aplikace nebo při ukončení aplikace. Samozřejmě si můžeš ukládat "mezivýsledky", ale data máš pořád v poli nebo listu, takže když budeš hledat informace o uložené osobě, tak je budeš hledat v poli (listu) a do souboru nemusíš.
A příklady s polem? No můžeš to udělat podobně jako to napsal splite:
class databazeOsob
{
private osoba[] databaze;
private int index;
private int maximum;
public databazeOsob()
{
databaze = new osoba[20];
index = 0;
maximum = 20;
}
public databazeOsob(int pocet)
{
databaze = new osoba[pocet];
index = 0;
maximum = pocet;
}
public bool vlozOsobu(string mesto, string jmeno)
{
if (index >= maximum) return (false);
databaze[index] = new osoba(mesto, jmeno);
index++;
return (true);
}
public bool zmenOsobu(int index, string jmeno, string mesto)
{
if ((index < 0) || (index >= this.index))
return (false);
databaze[index].jmeno = jmeno;
databaze[index].mesto = mesto;
return (true);
}
public osoba this[int index]
{
get
{
if ((index < 0) || (index >= this.index))
return (null);
return (databaze[index]);
}
}
public osoba this[string jmeno]
{
get
{
for (int i = 0; i < index; i++)
{
if (databaze[i].jmeno == jmeno)
return (databaze[i]);
}
return (null);
}
}
public void Save(string jmenoSouboru)
{
TextWriter textWrite = new StreamWriter(jmenoSouboru, false);
for (int i = 0;i < index;i++) {
textWrite.WriteLine(databaze[i].jmeno + "," + databaze[i].mesto);
}
textWrite.Close();
}
public void Load(string jmenoSouboru)
{
StreamReader reader = new StreamReader(jmenoSouboru);
string line;
string[] value;
while ((line = reader.ReadLine()) != null)
{
value = line.Split(',');
vlozOsobu(value[0], value[1]);
}
reader.Close();
}
// a tak dale, metod by se dalo vymyslet nepocitane :)
}
a použití:
databazeOsob db = new databazeOsob(36);
databazeOsob jinaDB = new databazeOsob();
osoba x;
db.vlozOsobu("praha", "josef");
db.Save("C:\\moje.db");
jinaDB.Load("C:\\moje.db");
jinaDB.zmenOsobu(0, "pepa", "z depa");
jinaDB.vlozOsobu("horni dolni", "blb");
x = jinaDB[1];
x = jinaDB[10];
x = jinaDB["pepa"];
if (x != null)
{
// a ve formulari ....
//TextBox1.Text = x.jmeno;
//TextBox2.Text = x.mesto;
}
To liborb : Vůbec si mě neodradil - naopak :smile1: . Díky za takhle konkrétní ukázku, jen jsem to zatím letmo projel a budu se na to muset podívat ještě párkrát než mi vše dojde :-) , ale myslím si že ještě budu muset napsat :-/ ..
Každopádně by mě zajímal Tvůj názor, jestli má cenu, když se to takhle učím od začátku, "dělat na věcech" jako je tato, když sám bych to v životě nedal dohromady, ale zase vidím ten krásný cíl, že by to mohlo někomu k něčemu být. Nebo bys mi spíš doporučil, abych dělal jednoduché věcičky, které nebudou mít v podstatě využití. Chápu že je to individuální... Zatím jsem přečetl jednu knížku pro začátečníky VS 05, pak jednu obecně o OOP, teď se učím ze seriálu na zive.cz. Každopádně praxe trošku pokulhává jak vidíš.. Tak mě jen zajímá jak to vidí někdo o dost zkušenější.
Samozřejmě po seriálu na 'živě' neskončím s učením, ale zase bych nerad někoho obtěžoval svými lamerskými problémy :smile14: . I když zase nikdo učený z nebe nespadl.. Jakým způsobem ses propracoval třeba Ty k tomu co znáš?
Díky, s pozdravem Hoffik
Normálně bych zůstal u "náznaků", ale když k tomu měl splite tolik poznámek :smile1: . A klidně sem klidně piš dál, on se vždycky někdo najde.
A můj názor? Jestli se máš pouštět do něčeho, na co zatím nestačíš? No ... a jak jinak bys chtěl růst :smile1: . Můžeš si dělat nesmyslné věci, které k ničemu nebudou, ale pocvičíš si na tom jednotlivé detaily (vlastnosti, dědění, abtraktní třídy ....). A samozřejmě není na škodu dělat něco, co má nějaký cíl. Rozhodně je to více motivující. Kombinuj oba přístupy a pomalu postupuj vpřed (taky jsem to tak dělal). Mít cíl, kterého chceš dosáhnout, je dobrá motivace.
A jak jsem se všechno naučil? To je námět na další offtopic vlákno :smile1: ... v mém případě je to v podstatě pouze a jenom z knih (až v poslední době se k tomu přidal i internet) a neustálým zkoušením v "praxi". A samozřejmě jsem byl taky začátečník, jako všichni na tomto serveru, i když se občas někteří tváří, že tomu tak nikdy nebylo :smile16: .
To liborb : No, kdyby si zůstal u náznaků, měl bych hned asi dalších 100 otázek :) takže díky tobě i splitovi :-D.
Souhlasím s tím růstem, máš pravdu, že je to asi jediná možnost. Motivace je motor..
No, napadlo mě že bych mohl založit spíš nový topic při takovéto otázce :-) .. Jen sem byl prostě zvědavý, odpověď jsem v podstatě dostal.
No a k tomuto serveru - právě že než jsem se vůbec zaregistroval tak jsem pár topiců pročítal a zjistil jsem, že je tu dost lidí, kteří si nechtějí jen zvyšovat ego, ale dokážou mít i trpělivost a chuť pomoct. Ne všude to tak chodí ;).
Super, děkuju
Všem děkuji za rady a trpělivost :o) ... Zjistil jsem, že na takovouhle věc asi ještě nemám, začnu procvičováním dílčích úkolů, a pak kdyžtak tenhle topic zase vyhrabu. Zdar a sílu
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Ukladani dat — založil Earl Cash
Ukládání dat na disk — založil sh00ter
C# Ukladani dat do .ini — založil nevimjakejmeno
AS - ukladaní a načitaní dat — založil Borisek
Ukládání dat na foru — založil Luky
Moderátoři diskuze