3. díl - Práce s textovými soubory v C#

C# .NET Práce se soubory Práce s textovými soubory v C#

V minulém dílu seriálu tutoriálů pro C# .NET jsme si ukázali, jak fungují přístupová práva v systémech Windows. Nejjednodušší cestou, jak uložit data aplikace na pevný disk, je využít textové soubory. Se soubory s příponou .txt jste se jistě všichni již setkali. Text je v nich uložen jednoduše na jednotlivých řádcích. K oddělení řádků se využívá speciálních znaků, které jsou bohužel specifické pro každý operační systém. Toto však za nás naštěstí vyřeší C#.

Pozn.: V různých materiálech se můžete setkat s použitím různých tříd a různých způsobů k zápisu do souborů. .NET framework se v čase vyvíjel a pro některé funkčnosti poskytuje kvůli kompatibilitě i starší nebo komplikovanější konstrukce. Budu se zde snažit ukazovat způsoby, které jsou nejjednodušší a nejnovější.

Zápis textu do nového souboru

Nejprve si pojďme vytvořit nový textový soubor a něco do něj zapsat. Vytvořte si nový projekt (konzolovou aplikaci) s názvem TextoveSoubory. K zapisování do textových souborů nám .NET poskytuje třídu StreamWriter.

Ve zdrojovém kódu si nejprve do using přidejme System.IO. Nyní vytvořme blok using a založme v něm novou instanci StreamWriter. Jak již víme z předchozích dílů, using se nám automaticky postará o zavření souboru po dokončení zápisu/čtení. Do konstruktoru napíšeme cestu k našemu souboru.

using (StreamWriter sw = new StreamWriter(@"soubor.txt"))
{
}

Náš StreamWriter je nyní nasměrovaný na správný soubor. Nový řádek zapíšeme pomocí metody WriteLine. Po dokončení zápisu musíme zavolat metodu Flush, která se stará o vyprázdnění bufferu. S tím se zde nebudeme zatěžovat, postačí nám vědět, že námi zapsané řádky mohou zůstat chvíli ve vyrovnávací paměti a my pomocí Flush vynutíme jejich zápis.

Kód se nám tedy rozrostl a může vypadat např. takto:

using (StreamWriter sw = new StreamWriter(@"soubor.txt"))
{
        sw.WriteLine("První řádek");
        sw.WriteLine("Tento text je na druhém řádku");
        sw.WriteLine("A do třetice.");
        sw.Flush();
}

Po spuštění se vytvoří soubor.txt ve složce s naším projektem, přesněji v bin/debug. Jak se správně v C# vypořádat s cestou k souboru a právy jsme si již ukazovali a zde to pro jednoduchost zanedbáme. Vidíme, že soubor existuje a opravdu obsahuje náš text:

Zápis textových souborů v C# .NET

Připsání textu do existujícího souboru

Pokud soubor neexistuje, kód výše ho vytvoří. Pokud existuje, bude přepsán. Toto chování můžeme změnit pomocí 2. parametru konstruktoru objektu StreamWriter. Pokud ho nastavíme na true, provede se tzv. append (připsání). Takto do existujícího souboru připíšeme nový řádek:

using (StreamWriter sw = new StreamWriter(@"soubor.txt", true))
{
        sw.WriteLine("Připsaný řádek");
        sw.Flush();
}

Dalším parametrem může být nastavení kódování, ale výchozí UTF-8 bude bohatě stačit.

Čtení existujícího souboru

Zbývá nám již jen umět soubor načíst. Není to o nic složitější, než zápis a opět k tomu máme v .NET frameworku připravenou třídu, konkrétně StreamReader. Použití je obdobné, namísto metody WriteLine použijeme ReadLine, která vrací řádek textu ze souboru a zároveň se přesune na řádek následující. Budeme ji tedy volat ve while cyklu. Podmínka pro ošetření vyjetí ze souboru je možná krkolomnější, kontrolujeme, zda proběhlo přiřazení nové řádky do proměnné.

Kód k výpisu obsahu souboru do konzole by vypadal takto:

using (StreamReader sr = new StreamReader(@"soubor.txt"))
{
        string s;
        while ((s = sr.ReadLine()) != null)
        {
                Console.WriteLine(s);
        }
}

Kód celého našeho programu vypadá nyní asi takto:

// zápis do souboru
using (StreamWriter sw = new StreamWriter(@"soubor.txt"))
{
        sw.WriteLine("První řádek");
        sw.WriteLine("Tento text je na druhém řádku");
        sw.WriteLine("A do třetice.");
        sw.Flush();
}
Console.WriteLine("Do souboru bylo zapsáno.");

// připsání textu do existujícího souboru
using (StreamWriter sw = new StreamWriter(@"soubor.txt", true))
{
        sw.WriteLine("Připsaný řádek");
        sw.Flush();
}
Console.WriteLine("Do souboru bylo připsáno.");

// výpis obsahu souboru
Console.WriteLine("Vypisuji soubor:");

using (StreamReader sr = new StreamReader(@"soubor.txt"))
{
        string s;
        while ((s = sr.ReadLine()) != null)
        {
                Console.WriteLine(s);
        }
}
Console.ReadKey();

A výsledek:

Zápis a čtení textových souborů v C# .NET

Třída File

.NET framework v sobě obsahuje statickou třídu File s předpřipravenými metodami, které práci se StreamReaderem/Stre­amWriterem sice plně nenahradí, ale ve velkém množství případů si s nimi vystačíme. Poslední příklad vypisující všechny řádky ze souboru by se dal zapsat takto (nezapomeňte na using System.IO):

string[] radky = File.ReadAllLines(@"soubor.txt");
foreach (string radka in radky)
{
    Console.WriteLine(radka);
}

Metoda ReadAllLines() nám vrátí všechny řádky textového souboru v poli stringů. Pokud se nejedná o nějaký velký soubor, je tato metoda mnohem jednodušší na použití. Na třídě File naleznete i další podobné metody jako WriteAllLines(po­leStringu, cestaKSouboru) nebo AppendAllLines(po­leStringu, cestaKSouboru), první zmíněná zapíše do souboru řádky z pole stringů, druhá připíše k existujícímu souboru řádky z pole stringů. Třída obsahuje také ekvivalenty metod, které nepracují s řádkami, ale souvislým textem. Jsou to WriteAllText(text), ReadAllText() a AppendAllText(tex­t).

V článku jsme opomenuli odchytávání výjimek a kontrolu práv. Do souborů také budeme chtít většinou ukládat spíše objekty, než řádky textu. To vše si ukážeme příště.


 

Stáhnout

Staženo 934x (24.76 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (13 hlasů) :
4.384614.384614.384614.38461 4.38461


 


Miniatura
Předchozí článek
Úvod do práce se soubory
Miniatura
Všechny články v sekci
Práce se soubory v C#
Miniatura
Následující článek
Uložení objektů do CSV v C#

 

 

Komentáře
Zobrazit starší komentáře (38)

Avatar
Tomáš Brůna
Redaktor
Avatar
Tomáš Brůna:

co to je za chybu?
Ps: používej prosím tlačítko odpovědět ;)

Odpovědět 26. dubna 18:38
Lepší být šprt než blbec :)
Avatar
lukas.kotyza
Člen
Avatar
Odpovídá na Tomáš Brůna
lukas.kotyza:

tady je ta chyba

System.NullRe­ferenceExcepti­on: Odkaz na objekt není nastaven na instanci objektu.
v a.MainForm..ctor() v c:\Users\Owner\Des­ktop\sklad vnt tht\a\MainFor­m.cs:řádek 34
v a.Program.Main(Strin­g[] args) v c:\Users\Owner\Des­ktop\sklad vnt tht\a\Program­.cs:řádek 27

Editováno 26. dubna 18:46
 
Odpovědět 26. dubna 18:45
Avatar
Tomáš Brůna
Redaktor
Avatar
Odpovídá na lukas.kotyza
Tomáš Brůna:

můžeš prosím ještě poslat kód desingeru?

Odpovědět 26. dubna 19:41
Lepší být šprt než blbec :)
Avatar
lukas.kotyza
Člen
Avatar
Odpovídá na Tomáš Brůna
lukas.kotyza:

kód designeru

/*
 * Created by SharpDevelop.
 * User: kotyza lukas
 * Date: 13.4.2016
 * Time: 19:11
 *
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
namespace a
{
        partial class MainForm
        {
                /// <summary>
                /// Designer variable used to keep track of non-visual components.
                /// </summary>
                private System.ComponentModel.IContainer components = null;

                /// <summary>
                /// Disposes resources used by the form.
                /// </summary>
                /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
                protected override void Dispose(bool disposing)
                {
                        if (disposing) {
                                if (components != null) {
                                        components.Dispose();
                                }
                        }
                        base.Dispose(disposing);
                }

                /// <summary>
                /// This method is required for Windows Forms designer support.
                /// Do not change the method contents inside the source code editor. The Forms designer might
                /// not be able to load this method if it was changed manually.
                /// </summary>
                private void InitializeComponent()
                {
                        this.label1 = new System.Windows.Forms.Label();
                        this.label2 = new System.Windows.Forms.Label();
                        this.label3 = new System.Windows.Forms.Label();
                        this.label4 = new System.Windows.Forms.Label();
                        this.vnt001 = new System.Windows.Forms.NumericUpDown();
                        this.vnt002 = new System.Windows.Forms.NumericUpDown();
                        this.vnt003 = new System.Windows.Forms.NumericUpDown();
                        this.vnt004 = new System.Windows.Forms.NumericUpDown();
                        this.btnvyrob1 = new System.Windows.Forms.Button();
                        this.numnasobic = new System.Windows.Forms.NumericUpDown();
                        this.panel1 = new System.Windows.Forms.Panel();
                        this.btnkontrola = new System.Windows.Forms.Button();
                        this.panel2 = new System.Windows.Forms.Panel();
                        this.panel3 = new System.Windows.Forms.Panel();
                        this.panel4 = new System.Windows.Forms.Panel();
                        this.odpovedlbl = new System.Windows.Forms.Label();
                        ((System.ComponentModel.ISupportInitialize)(this.vnt001)).BeginInit();
                        ((System.ComponentModel.ISupportInitialize)(this.vnt002)).BeginInit();
                        ((System.ComponentModel.ISupportInitialize)(this.vnt003)).BeginInit();
                        ((System.ComponentModel.ISupportInitialize)(this.vnt004)).BeginInit();
                        ((System.ComponentModel.ISupportInitialize)(this.numnasobic)).BeginInit();
                        this.SuspendLayout();
                        //
                        // label1
                        //
                        this.label1.Location = new System.Drawing.Point(12, 59);
                        this.label1.Name = "label1";
                        this.label1.Size = new System.Drawing.Size(189, 20);
                        this.label1.TabIndex = 1;
                        this.label1.Text = "VNT003";
                        //
                        // label2
                        //
                        this.label2.Location = new System.Drawing.Point(12, 33);
                        this.label2.Name = "label2";
                        this.label2.Size = new System.Drawing.Size(189, 20);
                        this.label2.TabIndex = 2;
                        this.label2.Text = "VNT002";
                        //
                        // label3
                        //
                        this.label3.Location = new System.Drawing.Point(9, 9);
                        this.label3.Name = "label3";
                        this.label3.Size = new System.Drawing.Size(189, 20);
                        this.label3.TabIndex = 3;
                        this.label3.Text = "VNT001 ( kondenzátor )";
                        //
                        // label4
                        //
                        this.label4.Location = new System.Drawing.Point(12, 85);
                        this.label4.Name = "label4";
                        this.label4.Size = new System.Drawing.Size(189, 20);
                        this.label4.TabIndex = 4;
                        this.label4.Text = "VNT004";
                        //
                        // vnt001
                        //
                        this.vnt001.BackColor = System.Drawing.Color.Silver;
                        this.vnt001.Increment = new decimal(new int[] {
                                                                        100,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt001.Location = new System.Drawing.Point(207, 7);
                        this.vnt001.Maximum = new decimal(new int[] {
                                                                        1000000000,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt001.Minimum = new decimal(new int[] {
                                                                        1410065408,
                                                                        2,
                                                                        0,
                                                                        -2147483648});
                        this.vnt001.Name = "vnt001";
                        this.vnt001.Size = new System.Drawing.Size(74, 20);
                        this.vnt001.TabIndex = 5;
                        this.vnt001.Value = new decimal(new int[] {
                                                                        1000,
                                                                        0,
                                                                        0,
                                                                        0});
                        //
                        // vnt002
                        //
                        this.vnt002.BackColor = System.Drawing.Color.Silver;
                        this.vnt002.Increment = new decimal(new int[] {
                                                                        100,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt002.Location = new System.Drawing.Point(207, 31);
                        this.vnt002.Maximum = new decimal(new int[] {
                                                                        1000000000,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt002.Minimum = new decimal(new int[] {
                                                                        1410065408,
                                                                        2,
                                                                        0,
                                                                        -2147483648});
                        this.vnt002.Name = "vnt002";
                        this.vnt002.Size = new System.Drawing.Size(74, 20);
                        this.vnt002.TabIndex = 6;
                        this.vnt002.Value = new decimal(new int[] {
                                                                        500,
                                                                        0,
                                                                        0,
                                                                        0});
                        //
                        // vnt003
                        //
                        this.vnt003.BackColor = System.Drawing.Color.Silver;
                        this.vnt003.Increment = new decimal(new int[] {
                                                                        100,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt003.Location = new System.Drawing.Point(207, 57);
                        this.vnt003.Maximum = new decimal(new int[] {
                                                                        1000000000,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt003.Minimum = new decimal(new int[] {
                                                                        1410065408,
                                                                        2,
                                                                        0,
                                                                        -2147483648});
                        this.vnt003.Name = "vnt003";
                        this.vnt003.Size = new System.Drawing.Size(74, 20);
                        this.vnt003.TabIndex = 7;
                        this.vnt003.Value = new decimal(new int[] {
                                                                        500,
                                                                        0,
                                                                        0,
                                                                        0});
                        //
                        // vnt004
                        //
                        this.vnt004.BackColor = System.Drawing.Color.Silver;
                        this.vnt004.Increment = new decimal(new int[] {
                                                                        100,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt004.Location = new System.Drawing.Point(207, 83);
                        this.vnt004.Maximum = new decimal(new int[] {
                                                                        1000000000,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.vnt004.Minimum = new decimal(new int[] {
                                                                        1410065408,
                                                                        2,
                                                                        0,
                                                                        -2147483648});
                        this.vnt004.Name = "vnt004";
                        this.vnt004.Size = new System.Drawing.Size(74, 20);
                        this.vnt004.TabIndex = 8;
                        this.vnt004.Value = new decimal(new int[] {
                                                                        500,
                                                                        0,
                                                                        0,
                                                                        0});
                        //
                        // btnvyrob1
                        //
                        this.btnvyrob1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
                        this.btnvyrob1.Location = new System.Drawing.Point(534, 255);
                        this.btnvyrob1.Name = "btnvyrob1";
                        this.btnvyrob1.Size = new System.Drawing.Size(79, 38);
                        this.btnvyrob1.TabIndex = 9;
                        this.btnvyrob1.Text = "výrobek 1 ";
                        this.btnvyrob1.UseVisualStyleBackColor = true;
                        this.btnvyrob1.Click += new System.EventHandler(this.Btnvyrob1Click);
                        //
                        // numnasobic
                        //
                        this.numnasobic.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
                        this.numnasobic.BackColor = System.Drawing.Color.Silver;
                        this.numnasobic.Location = new System.Drawing.Point(482, 266);
                        this.numnasobic.Maximum = new decimal(new int[] {
                                                                        100000,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.numnasobic.Minimum = new decimal(new int[] {
                                                                        1,
                                                                        0,
                                                                        0,
                                                                        0});
                        this.numnasobic.Name = "numnasobic";
                        this.numnasobic.Size = new System.Drawing.Size(46, 20);
                        this.numnasobic.TabIndex = 10;
                        this.numnasobic.Value = new decimal(new int[] {
                                                                        1,
                                                                        0,
                                                                        0,
                                                                        0});
                        //
                        // panel1
                        //
                        this.panel1.BackColor = System.Drawing.Color.Maroon;
                        this.panel1.Location = new System.Drawing.Point(190, 12);
                        this.panel1.Name = "panel1";
                        this.panel1.Size = new System.Drawing.Size(11, 10);
                        this.panel1.TabIndex = 11;
                        this.panel1.Visible = false;
                        //
                        // btnkontrola
                        //
                        this.btnkontrola.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
                        this.btnkontrola.Location = new System.Drawing.Point(12, 270);
                        this.btnkontrola.Name = "btnkontrola";
                        this.btnkontrola.Size = new System.Drawing.Size(75, 23);
                        this.btnkontrola.TabIndex = 12;
                        this.btnkontrola.Text = "kontrola";
                        this.btnkontrola.UseVisualStyleBackColor = true;
                        this.btnkontrola.Click += new System.EventHandler(this.BtnkontrolaClick);
                        //
                        // panel2
                        //
                        this.panel2.BackColor = System.Drawing.Color.Maroon;
                        this.panel2.Location = new System.Drawing.Point(190, 33);
                        this.panel2.Name = "panel2";
                        this.panel2.Size = new System.Drawing.Size(11, 10);
                        this.panel2.TabIndex = 12;
                        this.panel2.Visible = false;
                        //
                        // panel3
                        //
                        this.panel3.BackColor = System.Drawing.Color.Maroon;
                        this.panel3.Location = new System.Drawing.Point(190, 56);
                        this.panel3.Name = "panel3";
                        this.panel3.Size = new System.Drawing.Size(11, 10);
                        this.panel3.TabIndex = 12;
                        this.panel3.Visible = false;
                        //
                        // panel4
                        //
                        this.panel4.BackColor = System.Drawing.Color.Maroon;
                        this.panel4.Location = new System.Drawing.Point(190, 82);
                        this.panel4.Name = "panel4";
                        this.panel4.Size = new System.Drawing.Size(11, 10);
                        this.panel4.TabIndex = 13;
                        this.panel4.Visible = false;
                        //
                        // MainForm
                        //
                        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                        this.BackColor = System.Drawing.Color.Silver;
                        this.ClientSize = new System.Drawing.Size(625, 305);
                        this.Controls.Add(this.odpovedlbl);
                        this.Controls.Add(this.panel2);
                        this.Controls.Add(this.panel3);
                        this.Controls.Add(this.panel4);
                        this.Controls.Add(this.btnkontrola);
                        this.Controls.Add(this.panel1);
                        this.Controls.Add(this.numnasobic);
                        this.Controls.Add(this.btnvyrob1);
                        this.Controls.Add(this.vnt004);
                        this.Controls.Add(this.vnt003);
                        this.Controls.Add(this.vnt002);
                        this.Controls.Add(this.vnt001);
                        this.Controls.Add(this.label4);
                        this.Controls.Add(this.label3);
                        this.Controls.Add(this.label2);
                        this.Controls.Add(this.label1);
                        this.Name = "MainForm";
                        this.Text = "SKLAD THT - VNT";
                        ((System.ComponentModel.ISupportInitialize)(this.vnt001)).EndInit();
                        ((System.ComponentModel.ISupportInitialize)(this.vnt002)).EndInit();
                        ((System.ComponentModel.ISupportInitialize)(this.vnt003)).EndInit();
                        ((System.ComponentModel.ISupportInitialize)(this.vnt004)).EndInit();
                        ((System.ComponentModel.ISupportInitialize)(this.numnasobic)).EndInit();
                        this.ResumeLayout(false);
                }
                private System.Windows.Forms.Label odpovedlbl;
                private System.Windows.Forms.Panel panel4;
                private System.Windows.Forms.Panel panel3;
                private System.Windows.Forms.Panel panel2;
                private System.Windows.Forms.Button btnkontrola;
                private System.Windows.Forms.Panel panel1;
                private System.Windows.Forms.NumericUpDown numnasobic;
                private System.Windows.Forms.Button btnvyrob1;
                private System.Windows.Forms.NumericUpDown vnt004;
                private System.Windows.Forms.NumericUpDown vnt003;
                private System.Windows.Forms.NumericUpDown vnt002;
                private System.Windows.Forms.NumericUpDown vnt001;
                private System.Windows.Forms.Label label4;
                private System.Windows.Forms.Label label3;
                private System.Windows.Forms.Label label2;
                private System.Windows.Forms.Label label1;
        }
}
Editováno 26. dubna 20:10
 
Odpovědět 26. dubna 20:08
Avatar
Tomáš Brůna
Redaktor
Avatar
Odpovídá na lukas.kotyza
Tomáš Brůna:

abych pravdu řekl, tak netuším :( leda že by jsi poslal celý projekt, toto:

using (StreamWriter sw = new StreamWriter(@"uloziste.txt"))
                     {

                             decimal x = vnt001.Value;
                             sw.WriteLine(x.ToString());
                     }
                     using (StreamReader sr = new StreamReader(@"uloziste.txt"))
                     {
                             string s;
                             while ((s = sr.ReadLine()) != null)
                             {
                                     MessageBox.Show(s);
                                             /*zatím to mám poslané do massage boxu ale to teď neřeším*/
                             }
                     }

u mně normálně jede

Odpovědět 26. dubna 20:17
Lepší být šprt než blbec :)
Avatar
lukas.kotyza
Člen
Avatar
Odpovídá na Tomáš Brůna
lukas.kotyza:

http://www.itnetwork.cz/dev-lighter/716

http://www.itnetwork.cz/dev-lighter/715

http://www.itnetwork.cz/dev-lighter/714

a ještě nejspíš by to nemělo mít vliv ale v jakém programu to otvíráš já to otvírám v sharpdevelopu

 
Odpovědět 26. dubna 20:35
Avatar
Tomáš Brůna
Redaktor
Avatar
Tomáš Brůna:

konečně..... :D :D...
snažíš se číst z neexistujícího numericUpDownu, teda snažíš ze z něj číst něž ho vůbec vytvoříš,
takže přesuň tohle:

InitializeComponent();

před to kde čteš.

http://www.itnetwork.cz/dev-lighter/717

Odpovědět 26. dubna 21:00
Lepší být šprt než blbec :)
Avatar
lukas.kotyza
Člen
Avatar
Odpovídá na Tomáš Brůna
lukas.kotyza:

už to funguje strašně moc děkuji zase jsem o něco chytřejší

 
Odpovědět  +1 26. dubna 21:07
Avatar
Aleš Horna
Člen
Avatar
Aleš Horna:

Ahoj, rád bych se zeptal, zda jde nějak zjistit počet řádků v textovém dokumentu? Děkuji

 
Odpovědět 2. května 16:20
Avatar
Lukas C#
Redaktor
Avatar
Odpovídá na Aleš Horna
Lukas C#:

Založ si int, který při každém přečení řádku ve while cyklu inkrementuješ.

 
Odpovědět  +1 2. května 16:22
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 48. Zobrazit vše