A legegyszerűbb alkalmazások mellett a legtöbb programnak fájlokat kell olvasnia vagy írni. Lehet, hogy csak egy konfigurációs fájlt, vagy egy szöveges elemzőt, vagy valami kifinomultabb oldalt olvas. Ez az oktatóprogram a véletlen hozzáférésű fájlok használatára összpontosít.
A véletlen hozzáférésű fájl I / O programozása C-ben
Az alapvető fájlműveletek a következők:
- fopen - nyisson meg egy fájlt - adja meg, hogyan nyitotta meg (olvasás / írás), és írja be (bináris / szöveg)
- fclose - zárjon be egy megnyitott fájlt
- fread - fájlból olvasható
- fwrite - írjon egy fájlba
- fseek / fsetpos - vigye a mutatót valahol a fájlba
- ftell / fgetpos - megmondja, hol található a mutató
A két alapvető fájltípus a szöveg és a bináris. Ebből a kettőből a bináris fájlok kezelése általában egyszerűbb. Ez az ok, és mivel a szövegfájl véletlen hozzáférése nem olyan, amit gyakran kell tennie, ez az oktatóprogram csak bináris fájlokra korlátozódik. A fent felsorolt első négy művelet mind szöveges, mind véletlen hozzáférésű fájlokra vonatkozik. Az utolsó kettő csak véletlenszerű hozzáférés céljából.
A véletlenszerű hozzáférés azt jelenti, hogy a fájl bármely részére áthelyezhető, és adatait olvashatja el vagy írhat róla anélkül, hogy a teljes fájlt át kellene olvasnia. Évekkel ezelőtt az adatokat nagyméretű számítógépes szalagon tárolták. Az egyetlen módszer a szalag egy pontjához jutáshoz az volt, hogy egészen átolvasta a szalagot. Aztán jöttek a lemezek, és most közvetlenül elolvashatja a fájl bármely részét.
Programozás bináris fájlokkal
A bináris fájl bármilyen hosszúságú fájl, amely bájtot tartalmaz 0 és 255 közötti értékekkel. Ezeknek a bájtoknak nincs más jelentése, ellentétben a szöveges fájlban, ahol 13 érték azt jelenti, hogy a kocsi visszatér, 10 azt jelenti, hogy a sor betáplálja, és 26 azt jelenti, hogy a fájl vége. A szöveges fájlokat olvasó szoftvernek ezeknek a más jelentéseknek kell foglalkozniuk.
A bináris fájlok bájtfolyamot jelentenek, és a modern nyelvek inkább adatfolyamokkal, mint fájlokkal dolgoznak. A fontos rész az adatfolyam, nem pedig honnan származik. Ban ben C, az adatokra akár fájlként, akár folyamként gondolkodhat. Véletlen hozzáférés esetén a fájl vagy adatfolyam bármely részét el lehet olvasni vagy írni. Szekvenciális hozzáférés esetén a fájlt vagy adatfolyamot már a kezdetektől fogva át kell hurkolni, mint egy nagy szalagot.
Ez a kódminta megmutatja, hogy egy egyszerű bináris fájl megnyitásra kerül az íráshoz, és be van írva egy szöveges karakterlánc (char *). Ezt általában szöveges fájllal látja, de szöveget írhat bináris fájlba.
Ez a példa megnyit egy bináris fájlt írásra, majd char * (karakterláncot) ír be. A FILE * változó visszatér a fopen () hívásból. Ha ez nem sikerül (lehet, hogy a fájl létezik, nyitott vagy csak olvasható, vagy hibás lehet a fájlnévnél), akkor a 0 értéket adja vissza.
A fopen () parancs megpróbálja megnyitni a megadott fájlt. Ebben az esetben a test.txt ugyanabban a mappában található, mint az alkalmazás. Ha a fájl tartalmaz elérési utat, akkor az összes visszajelzést meg kell duplázni. "c: \ mappa \ test.txt" helytelen; a "c: \\ mappa \\ test.txt" fájlt kell használni.
Mivel a fájlmód "wb", ez a kód bináris fájlba ír. A fájl akkor jön létre, ha nem létezik, és ha igen, akkor a benne levő minden törlődik. Ha a fopen hívása sikertelen, például azért, mert a fájl nyitva volt, vagy a név érvénytelen karaktereket vagy érvénytelen útvonalat tartalmaz, a fopen 0 értéket ad vissza.
Annak ellenére, hogy csak ellenőrizheti, hogy az lábak nem nulla-e (siker), ez a példa rendelkezik egy FileSuccess () függvénnyel, hogy ezt kifejezetten megtegye. Windows rendszeren megjeleníti a hívás sikere / kudarcát és a fájlnevet. Kicsit nehézkes, ha előadás után játszik, ezért korlátozhatja ezt a hibakeresésre. Windows rendszeren kevés a fejek által kiadott szöveg a rendszer hibakeresõjéhez.
Az fwrite () hívások kiadják a megadott szöveget. A második és harmadik paraméter a karakterek mérete és a karakterlánc hossza. Mindkettőt úgy definiáljuk, mint méret_t, amely nem jelölt egész szám. Ennek a hívásnak az eredménye a megadott méretű darabszámok írása. Vegye figyelembe, hogy a bináris fájlok esetén, még akkor is, ha karakterláncot (char *) írsz, nem ad hozzá semmilyen kocsi visszatérési vagy sor betáplálási karaktert. Ha ezeket akarja, akkor azokat kifejezetten bele kell foglalnia a karakterláncba.
Fájlmódok a fájlok olvasásához és írásához
Egy fájl megnyitásakor meg kell határoznia, hogyan kell megnyitni - akár újból kell létrehozni, akár felülírni, és szöveges vagy bináris, olvassa vagy írja-e, és ha csatolni szeretné. Ehhez egy vagy több fájlmód-specifikátort kell használni, amelyek egyidejű "r", "b", "w", "a" és "+" betűket tartalmaznak a többi betűvel kombinálva.
- r - megnyitja a fájlt olvasáshoz. Ez sikertelen, ha a fájl nem létezik, vagy nem található.
- w - üres fájlt nyit meg íráshoz. Ha a fájl létezik, annak tartalma megsemmisül.
- a - megnyitja a fájlt íráshoz a fájl végén (mellékletként) anélkül, hogy eltávolította az EOF jelölőt, mielőtt új adatokat írna a fájlba; előbb létrehozza a fájlt, ha nem létezik.
Ha a "+" fájlt hozzáadja a fájlmódhoz, három új módot hoz létre:
- r + - megnyitja a fájlt olvasáshoz és íráshoz egyaránt. (A fájlnak léteznie kell.)
- w + - üres fájlt nyit meg az olvasáshoz és az íráshoz egyaránt. Ha a fájl létezik, annak tartalma megsemmisül.
- a + - megnyitja a fájlt olvasáshoz és csatoláshoz; a mellékelt művelet magában foglalja az EOF jelölő eltávolítását, mielőtt új adatokat írnának a fájlba, és az EOF jelölőt az írás befejezése után visszaállítják. Először a fájlt hozza létre, ha nem létezik. Megnyitja a fájlt az olvasáshoz és a hozzáfűzéshez; a mellékelt művelet magában foglalja az EOF jelölő eltávolítását, mielőtt új adatokat írnának a fájlba, és az EOF jelölőt az írás befejezése után visszaállítják. Először a fájlt hozza létre, ha nem létezik.
Fájlmód kombinációk
Ez a táblázat a fájlmód kombinációit mutatja mind a szöveges, mind a bináris fájlokhoz. Általában akár szöveges fájlból is olvassa, vagy írjon, de nem egyszerre mindkettőt. Bináris fájl esetén ugyanannak a fájlnak egyaránt olvashat és írni is tud. Az alábbi táblázat megmutatja, mit tehet az egyes kombinációkkal.
- r szöveg - olvasni
- rb + bináris - olvassa
- r + szöveg - olvasás, írás
- r + b bináris - olvasni, írni
- rb + bináris - olvasni, írni
- w szöveg - írás, létrehozás, csonkolás
- wb bináris - írjon, készítsen, csonkoljon
- w + szöveg - olvasás, írás, létrehozás, csonkolás
- w + b bináris - olvasás, írás, létrehozás, csonkolás
- wb + bináris - olvasás, írás, létrehozás, csonkolás
- szöveget - írj, készíts
- ab bináris - írjon, hozzon létre
- + szöveg - olvasás, írás, létrehozás
- a + b bináris - írjon, hozzon létre
- ab + bináris - írás, létrehozás
Kivéve, ha csak fájlt készít (használja a "wb"), vagy csak egyet olvassa (használja az "rb"), akkor megszabadulhat a "w + b" használatával.
Néhány megvalósítás más betűket is lehetővé tesz. Microsoftpéldául lehetővé teszi:
- t - szöveges mód
- c - kötelezz el
- n - nem kötelező
- S - gyorsítótár optimalizálása a szekvenciális hozzáféréshez
- R - gyorsítótárazás nem szekvenciális (véletlen hozzáférés)
- T - ideiglenes
- D - törlés / ideiglenes, amely lezárja a fájlt.
Ezek nem hordozhatóak, ezért használja őket a saját kockázatára.
Példa a véletlen hozzáférésű fájlok tárolására
A bináris fájlok használatának fő oka a rugalmasság, amely lehetővé teszi a fájl bárhol olvasását vagy írását. A szöveges fájlok csak egymás után olvashatnak vagy írhatnak. Az olcsó vagy ingyenes adatbázisok, mint például a SQLite és MySQL, csökkenti a véletlenszerű hozzáférés használatának szükségességét bináris fájlokon. A fájlrekordokhoz való véletlenszerű hozzáférés azonban kissé régimódi, ám mégis hasznos.
Példa vizsgálata
Tegyük fel, hogy a példa egy index- és adatfájl-párt mutat, amely sorokat tárol egy véletlen hozzáférésű fájlban. A húrok különböző hosszúságúak, és azokat 0, 1 és így tovább indexálják.
Két érvénytelen funkció van: CreateFiles () és ShowRecord (int recnum). A CreateFiles 1100 méretű char * puffert használ egy ideiglenes karakterlánc tartására, amely az msg formátumú karakterláncból áll, majd n csillagokból áll, ahol n 5 és 1004 között változik. Két fájl * jön létre wb filemode segítségével, az ftindex és az ftdata változóban. A létrehozás után ezeket használják a fájlok kezelésére. A két fájl
- index.dat
- data.dat
Az indexfájl 1000 típusú indextípust tartalmaz; ez a struct index típus, amelynek a két tagja van (fpos_t típus) és méretük. A hurok első része:
így tölti be az üzenet karakterláncát.
stb. Akkor ez:
kitölti az építményt a karakterlánc hosszával és az adatfájl azon pontjával, ahova a karakterlánc megírásra kerül.
Ezen a ponton mind az indexfájl struktúrája, mind az adatfájl karakterlánca beírható a megfelelő fájlokba. Bár ezek bináris fájlok, egymás után íródnak. Elméletileg írhatna rekordokat a fájl jelenlegi végén túl, de ez nem jó módszer, és valószínűleg egyáltalán nem hordozható.
Az utolsó rész mindkét fájl bezárása. Ez biztosítja, hogy a fájl utolsó része lemezre legyen írva. A fájlírás során sok írás nem közvetlenül a lemezre kerül, hanem rögzített méretű pufferekben van. Miután az írás kitölti a puffert, a puffer teljes tartalmát lemezre írják.
A fájlflush funkció kényszeríti az öblítést, és megadhatja a fájlöblítési stratégiákat is, de ezek szöveges fájlokhoz készültek.
ShowRecord függvény
Annak teszteléséhez, hogy az adatfájlból bármilyen meghatározott rekord lehívható-e, két dolgot meg kell tudnia: hol kezdődik az adatfájl és mekkora.
Az index fájl ezt csinálja. A ShowRecord funkció megnyitja mindkét fájlt, megkeresi a megfelelő pontot (recnum * sizeof (indextype)), és lehív egy bájtot = sizeof (index).
A SEEK_SET egy állandó, amely meghatározza, ahonnan készül a fseek. Ehhez két másik állandó van meghatározva.
- SEEK_CUR - keresse meg az aktuális helyzethez viszonyítva
- SEEK_END - keressen abszolút a fájl végétől
- SEEK_SET - keressen abszolút a fájl elejétől
A SEEK_CUR használatával mozgathatja a fájl mutatót méret szerint (index) előre.
Miután megszerezte az adatok méretét és helyzetét, csak be kell töltenie azokat.
Ebben az esetben használja a fsetpos () -ta index.pos típus miatt, amely fpos_t. Alternatív módszer a ftell helyett ftell és fsek helyett fgetpos használata. A fseek és ftell pár az int-rel működik, míg a fgetpos és fsetpos az fpos_t-t használja.
Miután elolvasta a rekordot a memóriába, hozzáad egy \ null karaktert, hogy helyes legyen c-húr. Ne felejtsd el, különben összeomlik. Mint korábban, mindkét fájlban meghívásra kerül az fclose. Bár nem veszít adatot, ha elfelejti a zárolást (ellentétben az írással), memóriaszivárgás merül fel.