Práce se soubory (a stdio.h)

V této kapitole začnu systematický výklad funkcí z knihovny <stdio.h>. Její název je odvozen ze slov standard input output, neboli standardní vstup a výstup. V předchozí kapitole jste se mohli podívat na přehled funkcí deklarovaných v souboru <stdio.h>. V této kapitole vysvětlím něco málo nezbytné teorie a v dalších kapitolách se podíváme na praxi. Doposud jste používali pouze vstup z klávesnice a výstup na monitor, ale už nastal čas naučit se pracovat se soubory :-).

O vstupu a výstupu

O vstupu a výstupu jsem povídal v souvislosti s funkcemi printf() a scanf(). Bylo by možná dobré, kdybyste si oprášili pojmy jako stdin, stdout a stderr, nebo výrazy bloková a znaková zařízení. Funkce printf() a scanf() jsou typickými představiteli knihovny <stdio.h>. Spoustu z toho, co ste se v souvislosti s těmito funkcemi dozvěděli (např. o formátovacích řetězcích) využijete i v dalších funkcích. Nakonec si ještě dovolím připomenout makro EOF (End Of File), které se používá k indikaci konce souboru.

Standardní vstup a výstup se považují také za soubory (s drobnými rozdíly, například „skutečné“ soubory mají své jméno a jsou někde uloženy …). Na rozdíl od ostatních souborů (např. textových, binárních a dalších speciálních souborů) jsou standardní vstup a výstupy otevřeny a programu přístupny automaticky při spuštění programu. Jak zajistit přístup k ostatním souborům, nebo jaký je rozdíl mezi textovými a binárními soubory se dozvíte při výkladu funkcí, které s těmito soubory pracují. Jelikož však už víte, co jsou to struktury, můžu vám ukázat deklarace standardního vstupu a výstupu:

Deklarace standardního vstupu, výstupu a chybového výstupu
FILE *stdin;Standardní vstup (typicky klávesnice)
FILE *stdout;Standardní výstup (typicky obrazovka)
FILE *stderr;Standardní chybový výstup (typicky obrazovka)

Jedná se o ukazatele na strukturu FILE. Ta je deklarovaná v souboru <stdio.h> a slouží k práci se soubory. Jak tato struktura vypadá není důležité. Zmiňuji se o ní v této chvíli proto, protože struktura FILE je argumentem spousty funkcí ze souboru <stdio.h>.

Přístup k souborům

Existují dva základní způsoby jazyka C, jak přistupovat k souborům. Buďto pomocí souborového proudu, nebo pomocí přímého volání.

Souborový proud

Knihovna <stdio.h> deklaruje přístup pomocí souborového proudu. Tento způsob přístupu k souborům je definován normou ANSI jazyka C (a také normou POSIX). K souborovému proudu se přistupuje pomocí struktury FILE. Díky normě ANSI máte jistotu, že používané funkce budou podporovány všemi („dobrými“) překladači. Díky tomu je převážně používán tento způsob práce se soubory. Tímto způsobem přístupu k souborům se budu zabývat nejdříve.

Souborové proudy mají obvykle vyrovnávací paměť (buffer). To znamená, že se při otevření načte z disku několik (stovek) bajtů do bufferu. Když se pak pokusíte něco přečíst, čtete rovnou z bufferu, což je rychlé. Když se dostanete na konec bufferu, načte se další (velký) kus z disku do pěmati (bufferu).

Při zápisu pracují buffery také. Zapisovaná data se nezapisují znak po znaku, ale nejdříve se nashromáždí v bufferu. Když jse buffer plný, pak se všechno zapíše na disk naráz (což je rychlejší). Vzpomeňte na funkci fflush().

Přímé volání

Přímé volání má přímou vazbu na systém. Tím je zaručena maximální rychlost přístupu k souborům, ale také implementační závislost. Pro funkce pracující s přímím voláním je potřeba použít knihovny <io.h>, <sys/stat.h> a <fcntl.h>. K souboru se nepřistupuje pomocí struktury FILE, ale pomocí manipulačního čísla tzv. deskriptoru souboru. Jedná se o datový typ int. Přímé volání není součástí normy ASCII, ale je definována normou POSIX.

Přímé volání se obvykle nepoužívá pro práci s běžnými soubory, ale například s deskriptory, které zprostředkovávají čtení dat po síti atp. Díky takovýmto deskriptorům můžete číst data z internetu (nebo z jiných „nesouborých“ zrdrojů). Dokonce existuje způsob, jak převést deskriptor souboru na souborový proud. O tom všem bude ještě řeč (částečně v programování pod Linuxem).

Textový a binární přístup k souborům

Existuje ještě jedno dělení přístupu k souborům a to na textový a binární přístup. Textový soubor je takový soubor, ve kterém je uložen pouze text. Toto překvapivé zjištění umožňuje zjednodušit některé souborové operace a zlepšit tak přenositelnost mezi různými operačními systémy.

Problém textových souborů spočívá, kromě kódování, ve znaku '\n'. Je to označení konce řádku ("Enter"). V DOSu/Windows je konec řádku dán dvěma bajty 13 a 10, zatímco v Linuxu pouze jedním (10). V jiných systémech je to pro změnu jen 13 (Apple). Při textovém přístupu k souboru můžete načítat a zapisovat textové řetězce. Přitom se nemusíte starat o to, jakým způsobem je znak '\n' interpretován. Nový řádek je vnitřně reprezentován jedním znakem, který je vždy roven '\n' (při čtení/zápisu souboru dochází k automatické konverzi).

13 (CR) odpovídá znaku „návrat vozíku“ (carridge return). To byl signál pro tiskárnu, že se má vrátit na začátek řádku papíru (doleva). 10 (LF) byl zase signál posunutí o řádek dále. Sekvence '\n' označuje LF, sekvence '\r' označuje CR.
Ale jak jsem psal, při výstupu funkce printf() a podobných se automaticky změní '\n' na takovou hodnotu (hodnoty), která je pro daný operační systém běžná.

Při binárním přístupu k souboru čtete i zapisujete data bajt po bajtu. V takovém případě, pokud chcete zapsat textový soubor, musíte zapsat znak '\n' v závislosti na tom, v jakém OS jej budete chtít číst. Při binárním přístupu máte tedy větší kontrolu nad zpracovávanými daty, ale práce s takovými soubory může být o něco náročnější.

Limity

V souboru <stdio.h> najdete makra FOPEN_MAX a FILENAME_MAX.

FOPEN_MAX udává podprou pro minimální počet otevřených souborových proudů (např. 16). Maximum otevřených souborů omezuje operační systém, mnohdy podle aktuální konfigurace systému. Pokud se pokusíte otevřít více souborů, otevření souboru selže.
FOPEN_MAX se týká limitu otevřených souborových proudů (v jeden okamžik), netýká se přímého volání.

FILENAME_MAX udává maximální délku jména souboru (např. 512 nebo 4096). V systému MS-DOS je známé omezení 8+3, tj. 8 znaků na jméno, tečka a tři znaky (přípona). Nicméně, FILENAME_MAX se vztahuje na délku absolutního jména souboru, tj. jména se jmény všech předcházejících adresářů.

Chcete-li, aby vaše programy byli maximálně přenositelné, využívejte těchto maker.

Komentář Hlášení chyby
Vytvořeno: 29.8.2003
Naposledy upraveno: 14.11.2015
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..