Fájl kezelés

A fájlkezelés az egyik legegyszerűbb dolog a Perl nyelvben. Mivel ez egy olyan terület, amelyik minden programban előfordul, és mivel a Perl elsősorban a UNIX operációs rendszerhez lett kitalálva, ahol a fájl alapfogalom, ezért nem csak könyvtári függvények, hanem programszerkezetek is rendelkezésre állnak a fájlok kezelésére.

A legegyszerűbb fájlkezelő utasítás, amellyel korábbi példákban is már találkoznod kellett a print. Ez az utasítás, vagy ha úgy tetszik beépített függvény egy fájlba, vagy a szabványos kimenetre írja ki a paraméterként megadott értékeket. A paraméterek lehetnek sztringek, valós vagy egész számok, változók, amelyek ilyen értékeket tartalmaznak, de lehetnek mutatók, vagy nem skalár értékek is. Ez utóbbi esetben a print utasítás valamilyen olyan karakter alakban írja ki a változó, vagy kifejezés értékét, hogy az legalább hibakeresési célra használható legyen.

Nézzünk egy egyszerű példát:

$a = 1; $b= 'alma\n'; $c = "alma\n"; $d = \$c;
print $a,$b,$c,$d;

és az eredményt:
1alma\nalma
SCALAR(0xcb7468)
Látszik, hogy $a értéke 1, $b értéke az aposztróf használata miatt nem lett kifejtve, és emiatt nem újsor karakter van a végén, hanem egy \ és egy n betű, de $c végén már valóban van egy soremelés. $d egy mutató, amelyik a $c változóra mutat, és ennek nyomtatott képe a SCALAR(xxx). A konkrét érték minden egyes futtatásnál más lehet, attól függően, hogy $c hova kerül a memóriában.

A print utasítás egyes paramétereit vesszőkkel választottuk el, azonban nagyon gyakran úgy akarunk kiíratni változó értékeket, hogy közbe mindenféle apróbb füzéreket helyezzük el. Például (ez a program az f2.pl fájlban van):

$a=3;$b=55;
print "A értéke=",$a," B értéke=",$b,"\n";

Ennek kimenete:
A értéke=3 B értéke=55

Aki azonban ezt a print utasítást leírta az nagyon nem Perl fejjel gondolkozott. Az IGAZI Perl programozó ilyenkor a következő sorokat írja (ez a program az f3.pl fájlban van):
$a=3;$b=55;
print "A értéke=$a B értéke=$b\n";

aminek kimenete
A értéke=3 B értéke=55

Ha ez nem ugyanaz, mint az előbb, akkor elrontottam a példát. (A példákat és a kiírt eredményeket a HTML fájlba egy Perl program állítja elő, így kizárt, hogy el legyen írva. Na jó: kevéssé valószínű.)

Természetesen nem csak a szabványos kimenetre lehet írni, hanem bármilyen fájlba, amelyiket írásra megnyitott a program. A fájlok megnyitására az open utasítás szolgál, a fájlok bezárására pedig a close. Nézzünk egy példát:

open(F,"<f2.pl");
open(G,">f3.bak");

while( $line = <F> ){
  $line =~ s/",//g;
  $line =~ s/,"//g;
  print G $line;
  }

close G;
close F;

Ez a kis program beolvassa az egyik fenti példaprogramot, és kiírja a f3.bak fájlba azt a verziót, amelyre azt mondtuk, hogy azt egy IGAZI Perl programozó készítette.

Egy kicsit lehet ebből a példából tanulni a reguláris kifejezéseket is, de most nem ez a lényeg. Figyeljünk arra, hogy hogyan nyitottuk meg a fájlt, hogyan írtunk bele, hogyan olvastunk belőle, és hogyan zártuk le.

Az első dolog amit megfigyelhetünk, az az, hogy a fájlokat nem változókkal azonosítjuk, hanem handlerekkel (ki tudja a hivatalos terminológiát erre a szóra? fogantyú?). Ez azt jelenti, hogy a fájl azonosító elé nem írunk $ jelet, és általában nagybetűt szoktunk használni a fájlazonosításra a programon belül, de ez csak konvenció, nem kötelező.

A másik dolog, amit meg lehet figyelni, hogy az open utasítás második argumentuma nem egyszerűen a fájl neve, hanem egy olyan füzér, amely tartalmazza a fájl nevét, de azt is, hogy a fájlt hogyan akarjuk megnyitni: írásra, olvasásra, vagy mindkettőre (ez utóbbira az előző példában nincs minta, majd még lesz).

Ha az open utasításban a második argumentumban a fájl neve előtt nincsen semmilyen jel, akkor a fájlt olvasásra nyitjuk meg. Ha < jel van a fájlnév előtt, az ugyanaz, mintha nem használtunk volna semmilyen jelet. Általában szokás ezt használni, annak ellenére, hogy ez a default, mert olvashatóbbá teszi a programot.

Ha a fájl neve előtt > jel van, akkor írásra nyitottuk meg a fájlt. Ha a fájl neve előtt <jel van, akkor olvasásra. Ezen kívül még használható a >> jel a fájlhoz való hozzáírásra, a +< a fájl írására és olvasására. Erre használható a +> jel is, ez azonban megnyitáskor törli a fájlt.

A fájlműveletek mindig a fájl aktuális pozíciójára vonatkoznak, amelyet egy fájl foganytű (handle) tartalmaz. Amikor kiírunk valamit, akkor oda íródik a szöveg ahova a foganyú mutató mutat, és ezután a fogantyú mutató a kiírt szöveg utánra fog mutatni. Amikor beolvasunk valamit egy fájlból, akkor onnan történik az olvasás ahova a fogantyú mutató mutat, majd az olvasás után a fogntyú motató a beolvasott adatok utánra fog mutatni. Ez olyan, mint más nyelveknél.

Egy fájlból olvasni a alakban lehet, ahol a kisebb és a nagyobb jelek közé kell írni a fájlkezelőt. Ez az utasítás skalár környezetben egy rekordot olvas be, lista környezetben pedig a hátralevő rekordok listáját. Egy rekord általában egy sor, mivel a rekord határoló karakter $/-ben megadva LF, de ha $/-nek más értéket adunk, akkor a beolvasás is másképp hajtódik végre. A végletekig elmenve ha a $/ változónak undef értéket adunk, akkor egész fájlokat tudunk változóba nagyon gyorsan beolvasni.

Ha egy fájlon belül akarjuk mozgatni a fogantyú mutatót, akkor erre a legegyszerűbb módszer a seek függvény meghívása. Ennek formája:

seek FILEFOGÓ,POZÍCIÓ,HONNAN
A FILEFOGÓ a fájlkezelő, a POZÍCIÓ az a hely ahova állítani szeretnénk a mutatót, a HONNAN paraméter pedig lehet 0, 1 vagy 2. Ha HONNAN 0 akkor a fájlon belül POZÍCIÓ a fájl elejétől számít. Ha HONNAN egy, akkor a mutató pillanatnyi pozíciójához képest fog elmozdulni, ha pedig 1, akkor a fájl végétől számítva.

Általában ajánlatos ezt a függvényt meghívni minden olvasási és írási művelet között. Ennek az oka nem a Perl nyelvben keresendő, hanem azokban a könyvtári függvényekben, amelyeket az operációs rendszer biztosít a Perl programok számára. A seek meghívásának a hatására a kiírandó adatok kikerülnek a pufferből, míg egy olvasás utáni írásnál egyes operációs rendszereken nem.

Ha azt akarjuk megtudni, hogy a fájlfogantyú mutatója éppen hova mutat, akkor a tell függvényt hívhatjuk meg. Argumentuma a fájlfogantyú, ha nem adunk meg argumentumot, akkor az utoljára olvasott fájlt fogja használni.

Egy fájl hosszát le lehet rövidíteni a truncate függvénnyel. Ennek két argumentuma van: a fájlfogantyú, és a megkívánt hossz.

Amikor egy fájlba írunk, vagy olvasunk onnan, akkor előfordulhat, hogy más is hozzá akar férni a fájlhoz. Ez pedig gondot okozhat, ha egyszerre több processz is ír a fájlba. Ha tehát egy fájlt le akarunk foglalni, akkor a flock függvényt kell használni. Ennek két argumentumot kell megadni. Az első a fájlfogantyú, a másodika lezárás módja:

A flock függvény addig fog várni, amíg hozzá nem lehet a megfelelő módon férni a fájlhoz. Fontos, hogy eközben a fájlmutató értéke nem változik. Ha például egy fájlhoz hozzá akarunk írni, vagyis a >> jelet használtuk a fájl megnyitására, majd ezután a megnyitott fájlt megpróbáljuk lezárni flock függvénnyel, akkor ezután egy seek F,2 függvényhívást is meg kell ejtenünk, hogy a fájlmutató a fájl végére mutasson.

A fájlokat kezelő függvényeknél általában nem csak egy fájlfogantyú nevet lehet megadni, hanem használni lehet ehelyett változót, amelynek értéke a fájlfogantyú neve. Ez alól Win32 környezetben egyes Perl verziók kivételek, ahol a truncate függvény hibás, és emiatt itt csak kerülő út alkalmazható.

Vannak még más fájlkezelő függvények is, ezekről részletesen a itt.


Verhás Péter Home Page . . . . . . Perl röviden, tartalomjegyzék