Weblabor - A kiindulopont webmestereknek
Leírások+Referenciák / Perl röviden / 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.

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 <F> 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 2, 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ásodik a lezárás módja:

  • 1 ??
  • 2 egyedi lezárás, más nem férhet hozzá a fájlhoz
  • 4 ??
  • 8 lezárás megszüntetése.

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 Perl beépített függvényeinél.