File-ok
A file-ok alapvetően kétfélék lehetnek: stream és rekord jellegű file-ok. Az egyszerű karaktersorozatból álló file-okat, azaz a text-file-okat a PL/I-ben stream jellegű file-oknak nevezzük. Egy-egy beolvasás vagy kiírás közben általában konverzióra kerül sor, amelynek során a számokat belső ábrázolású (pl. bináris) alakról karakteres alakra hozzuk (ill. fordítva).
Azokat a file-okat, amelyeknél az átvitel konverzió nélkül zajlik, rekord jellegű file-oknak nevezzük. Egy átvitel ilyenkor egy rekord mozgatását jelenti. Egy file lehet blokkolt, s a blokk egynél több rekordot is tartalmazhat. Fizikai szinten mindig egy egész blokkot tudunk csak átvinni. Ezért a memóriában a PL/I kialakít egy puffert, s a fizikai szintű átvitel mindig a puffer és a berendezés között zajlik, míg az I/O utasítások csak a program változói és a puffer között végeznek rekordonként adatmozgatást. Egy file-ban a rekordok hossza lehet egyforma, ekkor fix rekordhosszúságú file-ról beszélünk, ellenkező esetben azt mondjuk, hogy a file változó rekordhosszúságú.
A file-okkal kapcsolatban meg kell különböztetnünk két
fogalmat: a file-ok szervezését (felépítését) és a file-hoz való hozzáférést, a
file kezelését. Egy file lehet soros (szekvenciális) szervezésű, amikor a
rekordok egymás után helyezkednek el a file-ban, s azoknak semmiféle
azonosítójuk nincs, vagy pedig lehet indexes (kulcsos) file, amikor mindegyik
rekord rendelkezik egy egyértelmű azonosítóval (kulccsal), de a rekordoknak a
file-beli helyére nem írunk elő megkötéseket. A file kezelése lehet
szekvenciális, ami azt jelenti, hogy a rekordok átvitelére a fizikai
elhelyezkedésük sorrendjében kerül sor, vagy lehet direkt (közvetlen), amikor a
rekordokat tetszőleges sorrendben elérhetjük. Kulcsos file-okra is megengedett a
szekvenciális hozzáférés.
A stream jellegű file-ok csak szekvenciálisan
kezelhetők. Az, hogy a file szervezése és elérése milyen lehet, nagyban függ a
file hordozójától (pl. lyukkártya, mágnesszalag, mágneslemez stb.) is.
A
programban használt file-okat, azok típusát, attribútumait a deklarációs részben
definiálni kell.
file-változó FILE jelleg mód hozzáférés pufferezés
ENVIRONMENT szervezés kizárólagosság;
A jelleg leírására a STREAM vagy a
RECORD szó használható. Az átvitel módja lehet INPUT, OUTPUT, PRINT vagy UPDATE
(a PRINT csak stream jellegű, az UPDATE csak rekord jellegű file-okra
megengedett). A hozzáférés definiálására a SEQUENTIAL és a DIRECT szavakat
használhatjuk, s még azt is megadhatjuk, hogy a file BUFFERED vagy UNBUFFERED
(mindkettő csak rekord jellegű file-nál adható meg). Az ENVIRONMENT
attribútumban géptől függően többféle, a file felépítésére vonatkozó opció
adható meg. Ha a deklaráció végéhez (a kizárólagosság helyére) hozzáírjuk az
EXCLUSIVE szót, az azt jelenti, hogy arra az időre, amíg a program megnyitva
tartja a file-t, más program nem használhatja azt.
File-ok megnyitása és
lezárása a file egyéb paramétereitől függetlenül ugyanolyan OPEN és CLOSE
utasításokkal történik. Ugyanabban az utasításban több file is megnyitható, ill.
lezárható :
A file-vége kezelése az ON-utasítás segítségével történik: olvasáskor a file végének elérése kivált egy ENDFILE eseményt, amit egy ON ENDFILE(fileváltozó) utasítással kezelhetünk le.
Stream jellegű I/O
A file szervezési módjára vonatkozó információkat az
ENVIRONMENT attribútumhoz tartozó szervezési opciók között adjuk meg (az
opciókat szóközök választják el).
A stream jellegű I/O két műveletből áll:
A fileváltozó rész elhagyható, ekkor az átvitel az elsődleges perifériára irányul. Az utasításban szereplő specifikáció azoknak a változóknak és kifejezéseknek a felsorolása, amelyek a beolvasott értéket felveszik, ill. amelyeknek az értéke kiíródik. A utasításban megadhatók skalár változók, szelekciós kifejezések (pl. indexelés, SUBSTR), tömbnevek, struktúraváltozók és implicit ciklusok. A utasításban ezeken felül megadhatók még egyszerű kifejezések, tömbkifejezések és struktúra-kifejezések is.
A nyelv stream jellegű utasításai (GET/PUT) nincsenek tekintettel a berendezés blokkhosszára, folyamatosan viszik át a karaktereket, s ha pl. a sornyomtatón közben a sor betelik, az átvitelt automatikusan folytatják a következő sorban.
Az input stream-ben az adatokat változónév=érték formában (!)
kell megadni, s ezeket az elemeket szóköz vagy vessző választhatja el. A
felsorolt adatok után pontosvesszőnek kell állnia. Ha a GET utasításban megadott
nevek és az inputban levő nevek nem egyeznek meg, az hibát okoz. A GET utasítás
úgy is használható, hogy egyetlen változót sem adunk meg. A beolvasás ekkor is
ugyanúgy megtörténik, azaz az inputban megnevezett változók felveszik az
egyenlőségjel után álló értéket, csak a rendszernek nem lesz módja az azonosítók
ellenőrzésére.
Az eddig említett két forma nagyon egyszerűen használható, viszont a velük
megjeleníthető forma igencsak igénytelen. A bonyolultabb input- és
output-formátumok kezelésére a PL/I (kisebb változtatásokkal) átvette a FORTRAN
nyelv FORMAT utasítását.
A FORTRAN-ban tapasztalt módon, a felsorolt
változóknak rendre megfelel egy-egy formátumspecifikáció a formátumlistáról,
amely leírja az érték pontos képét. A formátumlistán a konverziós specifikációk
közé ágyazva szerepelhetnek szerkesztési specifikációk is.
A konverziós specifikációkat az alábbiakban foglaljuk össze ( w, d előjel nélküli egészeket jelöl).
A szerkesztési specifikációkat az alábbiakban foglaljuk össze.
Rekord jellegű I/O
Rekord jellegű file-ok szervezési módjai
Soros file-ok
A soros file-ok a legegyszerűbb felépítésű file-ok. Ebben az esetben a
rekordok közvetlenül egymás után helyezkednek el a file-ban, a rekordoknak
semmiféle azonosítójuk sincs. Bizonyos perifériák esetén, annak természetéből
fakadóan csak soros file-ok helyezhetők el (pl. lyukkártya, mágnesszalag). A
soros szervezésű file-ok csak szekvenciális eléréssel dolgozhatók fel.
Soros file-ok esetén az ENVIRONMENT attribútumhoz tartozó szervezési
opciók között a következőket adhatjuk meg :
Indexelt file-ok
Ebben az esetben a rekordokat kulccsal azonosíthatjuk. A kulcs egy legfeljebb
255 karakterből álló karaktersorozat lehet. A program átviteli utasításaiban
kulcsként megjelölhetjük a rekord egy mezejét, de a kulcs külön változóban is
megadható.
A file-kezelő rendszer három részre osztja a file-t: egy
indextáblára, a rekordok tárolására fenntartott területre (ún. elsődleges
adatterület), és egy ún. túlcsordulási területre (néha használnak másodlagos
túlcsordulási területet is). A file-kezelő az elsődleges adatterületet és a
kulcsértékek intervallumát egyaránt felosztja, s az indextáblába bejegyzi, hogy
a kulcsuk alapján a felosztás egy-egy részintervallumába eső rekordok az
elsődleges adatterület mely részén (nevezzük ezeket sávnak) találhatók.
A
rekordok elé a file-kezelő odaírja a rekord kulcsát is. Az elsődleges
adatterület egy-egy sávjában a rekordok a kulcsok szerint növekvő sorrendben
helyezkednek el.
Kereséskor annak a sávnak a megkeresése, ahol az adott
kulcsú rekord lehet, igen rövid ideig tart. A sávon belül a keresés már mindig
szekvenciális. (Ha új rekordok felírásakor egy sáv betelik, akkor az új rekord a
túlcsordulási területre kerül.) Ha a file-t szekvenciálisan olvassuk végig,
akkor a rekordokat éppen a kulcsok növekvő sorrendjében kapjuk meg.
Indexelt file-ok esetén az ENVIRONMENT attribútumhoz tartozó szervezési
opciók között a következőket adhatjuk meg :
REGIONAL(1) szervezésű file
REGIONAL(1) szervezésű file csak közvetlen elérésű tárolón, pl. mágneslemezen
alakítható ki. A file-t ún. régiókra bontjuk, ahol egy régió pontosan egy rekord
befogadására alkalmas (a rekordok azonos hosszúságúak). Egy file valahány
(mondjuk n) régióból áll, amiket képzeletben megsorszámozunk (0,...,n-1). A file
kijelölésekor a régiókba olyan értékek kerülnek, amelyekből megállapítható, hogy
az a régió még nem tartalmaz rekordot.
A kulcs típusa itt kötött, csak
PICTURE '(8)9' lehet. Egy rekord helyének a megkeresése úgy történik, hogy a
kulcsot leképezzük a 0,...,n-1 intervallumra. Az így megcímzett régió fogadja be
a rekordot. A leképezésnek egyértelműnek és lehetőleg egyenletesnek kell lennie.
Az egyértelműség a fontosabb kikötés, azt jelenti, hogy a leképezés minden
előforduló kulcshoz más régiósorszámot rendeljen. Az egyenletesség azt jelenti,
hogy a leképezés a 0,...,n-1 intervallumra egyenletes eloszlás szerint képezze
le a kulcsokat, mert így várhatóan tovább be lehet tartani a leképezés
egyértelműségét. A leképezést a programozó készíti el. A file-kezelő rendszer a
kulcsot itt nem jegyzi fel (nem írja a rekord elé).
REGIONAL(1)
szervezésű file-ok esetén az attribútumhoz tartozó szervezési opciók között a
következőket adhatjuk meg :
REGIONAL(3) szervezésű file-ok
A REGIONAL(1) módnál problémát okoz, ha a leképezés nem egyértelmű. Viszont
ennek a biztosítása nem minden esetben könnyű feladat. A REGIONAL(3) szervezési
mód esetében a régiók nem egy, hanem több rekord befogadására is képesek, s a
rekordok előtt ott van a rekord kulcsa is. Így, ha több kulcsra is ugyanazt a
régiót jelöli ki a leképező függvény, azok elférnek majd.
A REGIONAL(3)
szervezésű file-ok esetén az ENVIRONMENT attribútumhoz tartozó szervezési opciók
között a következőket adhatjuk meg :
Meg kell adni a REGIONAL(3)
megnevezést.
A rekordméretet F(r) formában kell megadni, ahol r a rekord
hossza byte-ban.
KEYLENGHT(n) definiálja a kulcs hosszát (byte-ban).
Rekord jellegű file-ok elérési módjai
Szekvenciális filekezelés
A szekvenciális file-ok deklarálásakor a DECLARE utasításban a hozzáférési
módok közül a SEQUENTIAL módot kell megadni. A szekvenciális elérés bármilyen
szervezési módú file esetén alkalmazható.
A file megnyitása, lezárása és a
file-vége kezelése ugyanúgy történik, mint bármely más file
esetén.
Szekvenciális feldolgozásnál a
Direkt filekezelés
Közvetlen (direkt) eléréssel azok a file-ok kezelhetők, amelyek szervezése
indexelt, REGIONAL(1) vagy REGIONAL(3). A közvetlen elérésű file-ok
deklarálásakor a DECLARE utasításban a hozzáférési módok közül a DIRECT módot
kell megadni.
A file megnyitása és lezárása ugyanúgy történik, mint bármely
más file esetén. A file-ok megnyithatók akár INPUT, OUTPUT vagy UPDATE
attribútummal is. (ENDFILE csak szekvenciális kezelésnél léphet fel.)
Direkt olvasásra a
utasításokat használhatjuk. Az első a megadott kulcsú rekordot olvassa be, a második a legutoljára beolvasott rekordot szekvenciálisan követő rekordot olvassa, s ennek a kulcsát értékül adja a KEYTO után megadott változónak.
Direkt írásra a
Egyéb
Megadhatók egyéb módosítók a típushoz, amelyek közül megadok néhányat: