Kromě nejjednodušších aplikací musí většina programů číst nebo zapisovat soubory. Může to být jen pro čtení konfiguračního souboru nebo textového analyzátoru nebo něco sofistikovanějšího. Tento tutoriál se zaměřuje na použití souborů s náhodným přístupem v C.
Programování I / O souborů s náhodným přístupem v C
Základní operace se soubory jsou:
- fopen - otevření souboru - určete, jak bude otevřen (čtení / zápis) a typ (binární / text)
- fclose - zavření otevřeného souboru
- fread - čtení ze souboru
- fwrite - zápis do souboru
- fseek / fsetpos - přesuňte ukazatel souboru někam do souboru
- ftell / fgetpos - řekne vám, kde se nachází ukazatel souboru
Dva základní typy souborů jsou text a binární. Z těchto dvou jsou binární soubory obvykle jednodušší řešit. Z tohoto důvodu a skutečnosti, že náhodný přístup k textovému souboru není něco, co musíte často dělat, je tento návod omezen na binární soubory. První čtyři výše uvedené operace se týkají textových souborů i souborů s náhodným přístupem. Poslední dva jen pro náhodný přístup.
Náhodný přístup znamená, že se můžete přesunout do kterékoli části souboru a číst nebo zapisovat z něj data, aniž byste museli číst celý soubor. Před lety byla data uložena na velkých válcích počítačové pásky. Jediným způsobem, jak se dostat k bodu na kazetě, bylo přečtení celé pásky. Pak přišly disky a nyní si můžete přečíst jakoukoli část souboru přímo.
Programování pomocí binárních souborů
Binární soubor je soubor libovolné délky, který drží bajty s hodnotami v rozsahu 0 až 255. Tyto bajty nemají na rozdíl od textového souboru žádný jiný význam, kde hodnota 13 znamená návrat řádku, 10 znamená posun řádku a 26 znamená konec souboru. Software, který čte textové soubory, musí řešit tyto další významy.
Binární soubory jsou tokem bajtů a moderní jazyky mají tendenci pracovat spíše s datovými proudy než se soubory. Důležitou součástí je spíše datový tok než to, odkud pocházel. v C, můžete o datech uvažovat jako o souborech nebo streamech. S náhodným přístupem můžete číst nebo zapisovat do kterékoli části souboru nebo proudu. Při sekvenčním přístupu musíte od začátku procházet souborem nebo proudem jako velká páska.
Tento ukázkový kód ukazuje jednoduchý binární soubor otevřený pro zápis, do kterého se zapisuje textový řetězec (char *). Normálně to vidíte u textového souboru, ale můžete psát text do binárního souboru.
Tento příklad otevře binární soubor pro zápis a poté do něj zapíše znak char * (řetězec). Proměnná FILE * je vrácena z volání fopen (). Pokud se to nezdaří (soubor může existovat a být otevřený nebo jen pro čtení nebo může dojít k chybě s názvem souboru), vrátí hodnotu 0.
Příkaz fopen () se pokusí otevřít zadaný soubor. V tomto případě je to test.txt ve stejné složce jako aplikace. Pokud soubor obsahuje cestu, musí být všechna zpětná lomítka zdvojnásobena. "c: \ folder \ test.txt" je nesprávný; musíte použít "c: \\ folder \\ test.txt".
Protože režim souboru je „wb“, tento kód zapisuje do binárního souboru. Soubor se vytvoří, pokud neexistuje, a pokud ano, bude odstraněno vše, co v něm bylo. Pokud selže volání fopen, pravděpodobně proto, že soubor byl otevřen nebo název obsahuje neplatné znaky nebo neplatnou cestu, vrátí fopen hodnotu 0.
Přestože byste mohli zkontrolovat, zda je ft nenulová (úspěch), tento příklad má funkci FileSuccess (), která to explicitně provede. V systému Windows vydává úspěch / neúspěch hovoru a název souboru. Je to trochu obtížné, pokud jste po výkonu, takže byste to mohli omezit na ladění. V systému Windows existuje jen malý režijní výstup do ladicího systému systému.
Fwrite () volá výstup zadaného textu. Druhým a třetím parametrem je velikost znaků a délka řetězce. Oba jsou definováni jako size_t, což je celé číslo bez znaménka. Výsledkem tohoto hovoru je zapsat počet položek zadané velikosti. U binárních souborů, i když píšete řetězec (char *), nepřipojí se k němu žádné znaky návratu vozíku nebo řádkového zdroje. Pokud je chcete, musíte je explicitně zahrnout do řetězce.
Režimy souborů pro čtení a zápis souborů
Když otevřete soubor, určíte, jak se má otevřít - zda se má vytvořit z nového nebo přepsat a zda se jedná o text nebo binární, číst nebo psát, a pokud k němu chcete přidat. To se provádí pomocí jednoho nebo více specifikátorů režimu souborů, které jsou jednotlivá písmena "r", "b", "w", "a" a "+" v kombinaci s ostatními písmeny.
- r - Otevře soubor pro čtení. Toto selže, pokud soubor neexistuje nebo nemůže být nalezen.
- w - Otevře soubor jako prázdný soubor pro zápis. Pokud soubor existuje, jeho obsah se zničí.
- a - Otevře soubor pro zápis na konci souboru (připojuje se) bez odstranění značky EOF před zápisem nových dat do souboru; vytvoří se nejprve soubor, pokud neexistuje.
Přidání "+" do režimu souboru vytvoří tři nové režimy:
- r + - Otevře soubor pro čtení i zápis. (Soubor musí existovat.)
- w + - Otevře soubor jako prázdný soubor pro čtení i zápis. Pokud soubor existuje, jeho obsah se zničí.
- a + - Otevře soubor pro čtení a připojení; připojovací operace zahrnuje odstranění značky EOF před zapisováním nových dat do souboru a značka EOF je obnovena po dokončení zápisu. Nejprve vytvoří soubor, pokud neexistuje. Otevře soubor pro čtení a připojení; připojovací operace zahrnuje odstranění značky EOF před zapisováním nových dat do souboru a značka EOF je obnovena po dokončení zápisu. Nejprve vytvoří soubor, pokud neexistuje.
Kombinace režimu souborů
Tato tabulka ukazuje kombinace režimu souborů pro textové i binární soubory. Obecně můžete číst nebo psát do textového souboru, ale ne obojí současně. S binárním souborem můžete číst i zapisovat do stejného souboru. Níže uvedená tabulka ukazuje, co můžete s každou kombinací udělat.
- r text - čtení
- rb + binární - čtení
- r + text - čtení, zápis
- r + b binární - čtení, zápis
- rb + binární - čtení, zápis
- w text - psát, vytvářet, zkracovat
- WB binární - zápis, vytváření, zkrácení
- w + text - čtení, zápis, vytváření, zkrácení
- w + b binární - čtení, zápis, vytváření, zkrácení
- wb + binární - čtení, zápis, vytváření, zkrácení
- text - psát, vytvářet
- ab binární - psát, vytvářet
- a + text - číst, psát, vytvářet
- a + b binární - zápis, vytváření
- ab + binární - zápis, tvorba
Pokud pouze nevytváříte soubor (použijte „wb“) nebo pouze čtete (použijte „rb“), můžete se dostat pryč pomocí „w + b“.
Některé implementace také umožňují jiná písmena. Microsoftnapříklad umožňuje:
- t - textový režim
- c - odevzdat
- n - nezávazný
- S - optimalizace ukládání do mezipaměti pro sekvenční přístup
- R - ukládání do mezipaměti nesekvenční (náhodný přístup)
- T - dočasný
- D - smazat / dočasně, což zabije soubor, když je zavřený.
Nejsou přenosné, takže je používejte na vlastní nebezpečí.
Příklad ukládání souborů s náhodným přístupem
Hlavním důvodem pro použití binárních souborů je flexibilita, která umožňuje číst nebo psát kdekoli v souboru. Textové soubory umožňují pouze číst nebo zapisovat postupně. S převahou levných nebo bezplatných databází, jako je SQLite a MySQL, snižuje potřebu použít náhodný přístup k binárním souborům. Náhodný přístup k záznamům o souborech je však trochu zastaralý, ale přesto užitečný.
Zkoumání příkladu
Předpokládejme, že příklad ukazuje pár indexu a datového souboru ukládající řetězce do souboru s libovolným přístupem. Řetězce jsou různé délky a jsou indexovány podle polohy 0, 1 atd.
Existují dvě neplatné funkce: CreateFiles () a ShowRecord (int recnum). CreateFiles používá char * buffer o velikosti 1100 k uložení dočasného řetězce tvořeného formátovacím řetězcem msg následovaným n hvězdičkami, kde n se pohybuje od 5 do 1004. Dva FILE * jsou vytvořeny pomocí wem filemode v proměnných ftindex a ftdata. Po vytvoření se tyto soubory používají k manipulaci se soubory. Oba soubory jsou
- index.dat
- data.dat
Indexový soubor obsahuje 1000 záznamů typu indextype; toto je strukturní indextyp, který má dva členy pos (typu fpos_t) a velikost. První část smyčky:
naplní řetězec msg jako je tento.
a tak dále. Pak toto:
vyplní strukturu délkou řetězce a bodem v datovém souboru, do kterého bude řetězec zapsán.
V tomto okamžiku lze do příslušných souborů zapsat strukturu indexového souboru i řetězec datového souboru. Přestože se jedná o binární soubory, jsou zapsány postupně. Teoreticky byste mohli zapisovat záznamy na pozici za aktuálním koncem souboru, ale není to dobrá technika k použití a pravděpodobně vůbec není přenosná.
Poslední částí je uzavření obou souborů. Tím je zajištěno, že poslední část souboru je zapsána na disk. Během zápisu souborů mnoho zápisů nejde přímo na disk, ale je uloženo v mezipaměti pevné velikosti. Jakmile zápis zaplní vyrovnávací paměť, celý obsah vyrovnávací paměti se zapíše na disk.
Funkce proplachování souborů vynucuje proplachování a můžete také určit strategie proplachování souborů, ale ty jsou určeny pro textové soubory.
Funkce ShowRecord
Chcete-li otestovat, že lze načíst jakýkoli určený záznam z datového souboru, musíte znát dvě věci: kde začíná v datovém souboru a jak je velký.
To je to, co dělá indexový soubor. Funkce ShowRecord otevře oba soubory, vyhledá příslušný bod (recnum * sizeof (indextype) a vyvolá počet bajtů = sizeof (index).
SEEK_SET je konstanta, která určuje, odkud se fseek provádí. K tomu jsou definovány dvě další konstanty.
- SEEK_CUR - hledat relativně k aktuální poloze
- SEEK_END - hledejte absolutně od konce souboru
- SEEK_SET - hledejte absolutně od začátku souboru
Pomocí SEEK_CUR můžete posunout ukazatel souboru dopředu podle velikosti (indexu).
Jakmile získáme velikost a polohu dat, stačí je načíst.
Zde použijte fsetpos () kvůli typu index.pos, který je fpos_t. Alternativní způsob je použít ftell místo fgetpos a fsek místo fgetpos. Dvojice fseek a ftell pracují s int, zatímco fgetpos a fsetpos používají fpos_t.
Po přečtení záznamu do paměti je přidán nulový znak \ 0, aby se proměnil v řádný řetězec c. Nezapomeňte na to, nebo dojde k havárii. Jako dříve, fclose je volán v obou souborech. Ačkoli neztratíte žádná data, pokud zapomenete fclose (na rozdíl od zápisů), budete mít nevracení paměti.