kategória | ||||||||||
|
||||||||||
|
||
Fájlkezelési alapfogalmak. Típusos fájlok, szövegfájlok. Fájlkezelő eljárások és függvények.
Az
eddig elkészített programokban használt adatok csak a program futása során, a
memóriában álltak rendelkezésre.
Ahhoz, hogy az adatokat bármikor elérhessük, rögzíteni kell õket
valamilyen háttértárolón. Erre szolgál a Pascalban a file típus, mellyel a
háttértáron elhelyezkedõ fizikai adatállományt kapcsolhatjuk egy
változónévhez. A file fogalmát kettõs értelemben használjuk, mivel a
számítógép input/output eszközeinek közvetlen elérését a Pascal eszköz
file-okkal biztosítja, míg az ún. lemez file-ok a lemezegységeken tárolt
adatállományokat jelentik.
A lemez file-ok szöveges, típusos vagy típusnélküli file-ok lehetnek. A
különbözõ állományokat a következõ módon
deklarálhatjuk:
var t: text;
f1: file of típus;
f2: file;
Az egyes fizikai állományokat az Assign eljárással rendelhetjük a változókhoz:
Assign(t,'C:/work/szoveg.txt');
Assign(f1,'autok.dat');
Assign(f2,utvonal);
A harmadik utasításban az állomány helyét az utvonal nevû string tartalmazza.
Szöveges file-ok
A szöveges file-ok minden sora egy-egy karakterlánc. Ha egy állományban akarunk
dolgozni, akkor elsõ lépésben
deklarálni kell egy file változót, majd az Assign paranccsal a lemezegységen
található file-hoz kell rendelni. Nem szükséges,
hogy már létezõ állomány legyen. Ezután következik a file megnyitása.
Egy szöveges file három módon nyitható meg:
Append(file_valtozo);
Reset(file_valtozo);
Rewrite(file_valtozo);
Az Append paranccsal egy létezõ állományt nyithatunk meg hozzáírásra. A file-mutató - mely az aktuális pozíciót mutatja a file-ban - az állomány végén áll. A Reset paranccsal egy létezõ állományt nyithatunk meg csak olvasásra, a file-mutató az állomány legelsõ sorára mutat. A Rewrite parancs új szöveg file-t hoz létre, vagy egy már meglévõ tartalmát kitörli, és újra- írásra teszi alkalmassá. A létezõ állományok megnyitásánál gyakori hiba, hogy a megadott fizikai állomány nem található, és a program futása megszakad. Célszerû ezt a problémát már a programozás során lekezelni, a kritikus programrészt és direktívák közé helyezve. Az IOResult függvény visszatérési értéke mutatja, hogy a megnyitás során volt-e probléma. Ha a függvény értéke nulla, akkor nem történt hiba.
Assign(t,'A:/eloadas.txt');
Reset(t);
if IOResult<>0 then Write('A file nem elérhetõ!');
Az IOResult függvény egyéb futási hibák ellenõrzésére is alkalmas. Ha sikeresen megnyitottuk az állományt, akkor írhatunk bele és olvashatunk belõle. Ha a szöveg file-t írásra nyitottuk meg (Append, Rewrite) akkor a kiíró eljárások módosított változataival írhatunk az állományba:
Write(file_valtozo, szoveg);
Writeln(file_valtozo,
szoveg);
A két eljárás közötti különbség, hogy a Write eljárás nem zárja le a file aktuális sorát, míg a Writeln lezárja és a következõ sor lesz az aktuális. Ha a szöveg file-t olvasásra nyitottuk meg (Reset) akkor az állományból a következõ parancsokkal olvashatunk ki sorokat:
Read(file_valtozo, szoveg_valtozo);
Readln(file_valtozo,
szoveg_valtozo);
A Read eljárás az éppen kiolvasott sorban marad, míg a Readln a sor olvasása után a következõ sor elejére lépteti a file- mutatót. A file-ok tartalmának olvasását érdemes ciklusba szervezni. Ilyenkor viszont tudni kell, hogy mikor értük el az állomány végét, és hogy le kell állítani a ciklust.
while not eof(f) do
begin
Readln(f,sor);
..
end;
Az eof függvény eredménye logikai érték, mely igaz akkor, ha a file-mutató az állomány végén áll egyébként hamis. A sorok olvasása addig folytatódik, amíg a függvény értéke nem true. A szöveges állományok lezárása a Close paranccsal történik:
Close(file_valtozo);
Nézzünk példát egy szöveges állomány kezelésére!
program filekezeles;
var f:text;
sor:string;
begin
Assign(f,'szoveg.txt');
Rewrite(f);
Clrscr;
repeat
Readln(sor);
Writeln(f,sor);
until sor='';
Clrscr;
Reset(f);
while not eof(f) do
begin
Readln(f,sor);
Writeln(sor);
end;
Close(f);
end.
A program egy szoveg.txt nevû text állományt hoz létre az aktuális könyvtárban. A sor változóba begépelt adatokat az f file-ba írja mindaddig míg egy üres sort nem írunk. Ezután a letörölt képernyõre kiíratjuk a file tartalmát, végül lezárjuk.
Típusos file-ok
A típusos file-ok alkalmazásával olyan adathalmazokat is
létrehozhatunk, melyek sorai azonos típusú (nem kizárólag szöveges) elemeket
tartalmaznak. Az ilyen állományok deklarációjában azt kell megadni, hogy a file
soraiban tárolt adatok milyen típusúak legyenek. A file típusa lehet
egyszerû vagy összetett, de nem lehet file vagy objektum típus. Például:
var f1:file of integer;
f2:file of real;
Azonban gyakrabban használunk összetett típusokat egy file típusaként.
type tanulotipus=record
neve:string[25];
osztalya:string[5];
atlaga:real;
end;
var f_iskola:file of tanulotipus;
Az f_iskola azonosítóhoz rendelt állomány minden sora egy-egy tanulo rekord lesz, és így az iskola összes tanulójának adatait egyetlen file-ban tárolhatjuk. A file megnyitására a már ismert eljárások használhatók (kivéve Append):
Reset(f_iskola);
Rewrite(f_iskola);
A szöveges állományoktól eltérõen, a Reset-tel történõ megnyitás után nem csak olvashatunk a file-ban, hanem írhatunk is hozzá. A Rewrite használatával is elvégezhetjük mind a két tevékenységet, de ha már létezõ file-t nyitunk meg így, akkor a tartalma elvész. A file-ba írás (Write, Writeln) ill. az abból való olvasás (Read, Readln) a szöveges állományoknál ismertetett módon történik. A típusos file-okban tetszés szerint mozoghatunk, ehhez a következõ parancsot használjuk:
Seek(file_valtozo, index);
A Seek eljárás paramétereként meg kell adni annak az állománynak az azonosítóját, amelyben mozogni akarunk, és annak a sornak a számát, ahová a file-mutatót állítani akarjuk. Fontos tudni, hogy a file elsõ sorának indexe 0, a másodiknak 1, és így tovább. Ahhoz, hogy az indexben megadott sorszám biztosan elérhetõ sort jelöljön, tudnunk kell a file pontos méretét, vagy a file-mutató aktuális helyét.
FileSize(file_valtozo)
FilePos(file_valtozo)
A
FileSize függvény visszatérési
értéke egy longint típusú szám, mely a file-ban található sorok száma (az
utolsó sor indexe). Ha az állomány üres, akkor a függvény értéke 0. A FilePos
függvény eredménye egy longint típusú szám, mely a file aktuális sorának
indexe. Ha a file-mutató az elsõ sorra mutat, akkor a függvény értéke 0.
Ha az aktuális pozíció a file vége, akkor a függvény értéke megegyezik a
FileSize függvény értékével. A Seek eljárásban az index helyén is alkalmazhatók
ezek a függ- vények.
Ha az állományunk utolsó soraiban olyan adatok vannak, melyeket törölni akarunk
a file-ból, akkor a file végét egy- szerûen levágjuk a Truncate
paranccsal:
Truncate(file_valtozo);
Az eljárás a file-mutató aktuális pozíciójától csonkolja a file-t, az utolsó sor az aktuális pozíció lesz. Készítsünk egy programot, mely egy már létezõ file-ban keres!
program filekezeles2;
type str25: string[25];
str5 : string[5];
tanulotipus=record
neve: str25;
osztalya: str5;
atlaga: real;
end;
var f_iskola: file of tanulotipus;
nev: str25;
osztaly: str5;
diak: tanulotipus;
van: boolean;
begin
Assign(f_iskola,'tanulok.dat');
Reset(f_iskola);
if IOResult<>0 then begin
Write('A file nem
elérhetõ!'); Halt(1);
end;
if FileSize(f_iskola)<>0 then begin
ClrScr;
Write('Kérem a tanuló nevét: ');
Readln(nev);
Write('Kérem a tanuló osztályát: ');
Readln(osztaly);
van:=false;
while (not
eof(f_iskola)) or (not van) do
begin
Readln(f_iskola,diak);
if (diak.neve=nev) and (diak.osztaly=osztaly) then
begin
Write('Átlaga: ',diak.atlag);
van:=true;
end;
end;
end else Write('A file üres');
end.
A program kikeresi a tanulok.dat állományból egy adott diák átlagát. Deklaráltunk egy tanulotipus rekordot, mely a tanulók adatait tartalmazza, és a file minden sora egy ilyen rekord. Az Assign eljárással a fizikai állományhoz rendeljük az f_iskola azonosítót, majd megnyitjuk a file-t. Ha valamilyen hiba történik a megnyitás során azt jelezzük. Ha a file nem üres akkor bekérjük a tanuló nevét és osztályát. A file-ban addig keresünk, amíg meg nem találjuk a keresett tanulót, vagy a végére nem érünk. Ha megtaláltuk a tanulót, akkor az átlagát a képernyõre írjuk és leállítjuk a ciklust.
Típus nélküli file-ok
A típus nélküli file-ok ismeretlen felépítésû állományok
kezelésére szolgálnak. Ezért az ilyen adathalmazok feldolgozásánál nem
logikailag elválasztható sorokkal végzünk mûveleteket, hanem fizikai
blokkokkal. Egy blokk alapértelmezés szerint 128 byte. A file megnyitásakor a
blokk mérete módosítható.
Reset(file_azonosito, blokkmeret);
Rewrite(file_azonosito,
blokkmeret);
Ha az alapértelmezés szerinti blokkméretet használjuk, akkor a típusos file-ok megnyitási parancsait lehet alkalmazni. A típus nélküli állományok I/O mûveleteire külön parancsok vannak a Pascalban.
BlockWrite(file_valtozo,puffer,blokkok,n);
BlockRead(file_valtozo,puffer,blokkok,n);
Mindkét eljárás ugyanolyan paramétereket használ. Az elsõ paraméter a file azonosítója, a második a felhasznált puffer, a harmadik paraméterben az egy lépésben írni ill. olvasni kívánt blokkok számát kell megadni. A negyedik paraméterben a ténylegesen beolvasott ill. kiírt blokkok számát adja vissza az eljárás, ez a paraméter el is maradhat.
type puff= array [1..32*512] of byte;
var f1,f2:file;
olv,irt:word;
puffer:puff;
A fenti deklarációval a következõképpen használjuk a blokkolvasó és -író utasításokat:
BlockRead(f1,puffer,SizeOf(puf),olv);
BlockWrite(f2,puffer,olv,irt);
Az
f1 állományból kiolvasott
adatok az f2-be kerülnek. A
SizeOf függvény a paraméterben megadott típus méretét adja
vissza byte-ban. Az f2 file-ba csak az f1-bõl ténylegesen kiolvasott adatok kerülnek.
A típus nélkül file-oknál is használhatók az állomány méretét és a file-mutató
aktuális pozícióját megadó függvények, valamint a pozícionáló eljárás. A
FileSize visszatérési értéke az egész blokkok száma a file-ban. A FilePos függvény
értéke az aktuális blokk sorszáma. A Seek eljárás pedig blokkonkénti
pozícionálást végez. A file-t a Close paranccsal zárjuk.
Könyvtárkezelés
A MS-DOS operációs rendszer állomány és könyvtárkezelõ
parancsainak megfelelõ eljárások léteznek a Pascal nyelvben.
MkDir(utvonal);
ChDir(utvonal);
RmDir(utvonal);
Rename(file_azonosító,uj_nev);
Erase(file_azonosító);
A file átnevezése és törlése nyitott állományon nem hajtható végre. Az állomány azonosítóját itt is az Assign eljárással rendeljük a fizikai állományhoz. A mûveletek sikerességét a már megismert IOResult függvénnyel vizsgálhatjuk.
:
4832