Soubory se využívají jako vstup aplikací, ale i pro uložení následných výstupů aplikací. Při volbě způsobu ukládání je nutné zvážit všechny výhody (např. jednoduchost) a nevýhody (nelze paralelizovat, obtížné řešení souběžných přístupů, atd.). V současné době se soubory nejčastěji využívají pro uložení konfigurace, která se při spuštění aplikace načte do paměti.

Binární a textové soubory

Soubory lze rozdělit do dvou základních kategorií dle jejich obsahu:

  • textové
  • binární

Binární soubory

  • Binární soubory ukládají data ve strojově čitelném formátu, který není určen pro běžné čtení člověkem.
  • Čtení a zápis binárního souboru vyžaduje přesnou znalost formátu dat – tzn. kde začínají jednotlivé bloky, jaká obsahují data (datové typy, délka a struktura).
  • Příklady binárních souborů:
    • obrázky (JPEG, PNG)
    • zvukové soubory (MP3, WAV)

Textové soubory

  • Textové soubory ukládají data jako posloupnost znaků (ASCII, UTF-8, UTF-16 apod.).
  • Jsou snadno čitelné člověkem.
  • Nejsou tolik efektivní z hlediska velikosti oproti binárnímu zápisu.

Textové soubory lze dále rozdělit dle obsahu:

  • Prostý a formátovaný text
  • strukturovaný text

Prostý a formátovaný text

  • prostý text (plain text) obsahuje data bez přesné struktury – typicky běžné zápisy textu (poznámky, logy).

Příklad prostého textu:

Toto je obsah textového souboru.
Může obsahovat libovolné řádky textu.

Strukturovaný text

  • strukturovaný text obsahuje data ve formátu vhodném ke strojovému zpracování.
  • využívá definovanou syntaxi a hierarchii.
  • příklady formátů: XML, JSON, CSV

Příklad strukturovaného textu (JSON):

{
	"Name": "Jan",
	"Age": 30
}

Přístupy k práci se soubory

.NET poskytuje dva hlavní přístupy k práci se soubory:

  • Práce pomocí streamů – práce s daty po bajtech či znacích, vhodné pro velké objemy dat nebo binární soubory.
  • Práce pomocí statických metod třídy File – pohodlný způsob práce s celými soubory najednou. Hodí se zejména pro textové soubory menšího rozsahu.

Práce pomocí Streamů

Streamy (datové proudy) jsou abstrakce toku dat, které umožňují čtení nebo zápis dat sekvenčně, tj. po částech, místo práce s celým souborem najednou. Více informací o streamech lze nalézt zde: Streamy.

Ukázka zápisu do souboru

using System.IO;
 
string cesta = "vystup.txt";
 
using (StreamWriter writer = new StreamWriter(cesta))
{
    writer.WriteLine("První řádek textu.");
    writer.WriteLine("Druhý řádek textu.");
    writer.WriteLine("Třetí řádek textu.");
}

Chybí ošetření výjimek

Pro zjednodušení kódu byl vynechán. Správné použití v Ošetření výjimek.

Ukázka čtení souboru po řádcích

using System.IO;
 
string cesta = "vystup.txt";
 
using (StreamReader reader = new StreamReader(cesta))
{
    string? radek;
    while ((radek = reader.ReadLine()) != null)
    {
        Console.WriteLine(radek);
    }
}

Chybí ošetření výjimek

Pro zjednodušení kódu byl vynechán. Správné použití v Ošetření výjimek.

Práce s třídou File

Třída System.IO.File poskytuje statické metody pro snadnou práci se soubory. Při těchto operacích se celý obsah souboru načte do paměti nebo obsah paměti uloží do souboru.

Načtení obsahu souboru

File.ReadAllText - Načtení celého obsah souboru do textového řetězce obsah.

string obsah = File.ReadAllText("data.txt");
Console.WriteLine(obsah);

Zápis textu do souboru

File.WriteAllText - Zápis textu do souboru

string obsah = "Toto je obsah souboru.";
File.WriteAllText("vystup.txt", obsah);

Další funkce

  • File.ReadAllLines - Čtení souboru po řádcích
  • File.WriteAllLines - Zápis více řádků do souboru
  • File.AppendAllText - Zápis textu na konec souboru

Ošetřování výjimek při práci se soubory

Při práci se soubory mohou nastat různé výjimky, které je nutné zachytit a ošetřit.

Typy výjimek při práci se soubory:

  • FileNotFoundException – soubor neexistuje
  • IOException – obecné chyby vstupu/výstupu
  • UnauthorizedAccessException – nedostatečná práva
  • DirectoryNotFoundException – adresář neexistuje

Ukázka ošetření výjimek

try
{
    string obsah = File.ReadAllText("data.txt");
    Console.WriteLine(obsah);
}
catch (FileNotFoundException ex)
{
    Console.WriteLine($"Soubor nebyl nalezen: {ex.Message}");
}
catch (IOException ex)
{
    Console.WriteLine($"Chyba I/O: {ex.Message}");
}