A PL/1 programozási nyelv

Input-output

Input-output

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ó :

OPEN FILE(fileváltozó); CLOSE FILE(fileváltozó); OPEN FILE(fileváltozó), FILE(fileváltozó); CLOSE FILE(fileváltozó), FILE(fileváltozó);

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:

GET FILE fileváltozó specifikáció
az input utasítás
PUT FILE fileváltozó specifikáció
az output utasítás

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.

GET FILE (fileváltozó) DATA specifikáció;

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.

PUT FILE (fileváltozó) DATA specifikáció;}
Kiíráskor ugyanazt a formátumot nyerjük, mint amit a GET utasítás számára meg kell adni az inputban: a megnevezett változók változónév=érték formában kiíródnak, az ilyen elemeket szóköz követi, az utolsót pedig pontosvessző.

GET FILE (file-változó) LIST specifikáció; PUT FILE (file-változó) LIST specifikáció;

Beolvasáskor az inputban az értékek tetszőleges formában megadhatók (ld. a literálok megengedett formáit). Az értékeket szóközzel vagy vesszővel kell elválasztani. Ha a GET utasításban tömbnév áll, a tömb értékeit sorfolytonosan kell megadni.
Kiíráskor az értékek a GET LIST formátumhoz hasonló formában jelennek meg.
GYOK : PROCEDURE OPTIONS(MAIN); DCL BE FILE INPUT ENV(F(80)); DCL KI FILE PRINT ENV(F(132)); DCL (A, B, C, X1, X2) FLOAT BIN; OPEN FILE(BE), FILE(KI); ON ENDFILE(BE) GOTO VEGE; ISM: GET FILE(BE) LIST (A, B, C); D = B * B $-$ 4 * A * C; IF D $<$ 0 THEN PUT FILE(KI) LIST (' KOMPLEX GYOKOK'); ELSE DO; X1 = ($-$ B + D**0.5) / (2 * A); X2 = ($-$ B $-$ D**0.5) / (2 * A); PUT FILE(KI) LIST (' X1 = ', X1, ' X2 = ', X2); END; GOTO ISM; VEGE: CLOSE FILE(BE), FILE(KI); END;

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.

GET FILE (fileváltozó) EDIT specifikáció formátum; PUT FILE (fileváltozó) EDIT specifikáció formátum;
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 formátumlistán a konverziós és szerkesztési specifikációkat vesszőkkel választjuk el. A specifikációk előtt ismétlési tényezők helyezhetők el. A formátumlista egy része zárójelbe tehető, s ez a zárójelezett rész is ellátható ismétlési tényezővel. Ez azt jelenti, hogy pl. (X(4), F(5), F(5), F(5), B(6), B(6)) ismétlési tényező alkalmazásával írható (X(4), 3F(5), 2B(6)) alakban is, vagy írható (X(4), F(5), 2(F(5), B(6)) alakban is. Az ismétlési tényező nemcsak számkonstans, hanem egész értékű kifejezés is lehet, az ilyen ismétlési tényezőt azonban kerek zárójelek közé kell zárni.

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.

  • X(w) - Figyelmen kívül hagyandó karakterhelyeket jelent.
  • COLUMN(n) - A fizikai blokkban az n. pozíción folytatja az átvitelt (ha ez visszalépést jelent egy korábbi pozícióra, akkor előbb átlép a következő fizikai blokkba).
  • SKIP(n) - n db fizikai blokkot előre lép (1 jelenti a következő blokkot).
  • LINE(n) - Abszolút függőleges pozícionálás a sornyomtatólapon: a lap n. sorában folytatja a nyomtatást (ha a lapon már túljutott az n. soron, akkor a következő lap n. sorában .
  • PAGE - Lapdobás. A nyomtatás a következő lap tetején folytatódik.
  • 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 :

  • A szervezési módjának megnevezése : CONSECUTIVE.
  • Fixhosszúságú rekordokból álló file rekordméretét F(b) vagy F(b,r) formában kell megadni, ahol b a blokk, r a rekord hossza byte-ban. Változó hosszúságú rekordokból álló file esetén a maximális blokkméretet kell megadni formában.
  • BUFFERS(1), ill. BUFFERS(2) formában adhatjuk meg, hogy a rendszer a puffereléshez egy vagy két puffert használjon.
  • 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 :

  • Az opciók között kell megadni az INDEXED megnevezést.
  • A rekordméretet F(b) vagy F(b,r) formában kell megadni, ahol b a blokk, r a rekord hossza byte-ban.
  • KEYLENGTH(n) definiálja a kulcs hosszát (byte-ban).
  • EXTENTNUMBER(n) definiálja az adatok tárolására kijelölt területek számát (ez minimálisan 2).
  • 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 :

  • Meg kell adni a REGIONAL(1) megnevezést.
  • A file rekordméretét F(r) formában kell megadni, ahol r a rekord hossza byte-ban.
  • 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

    READ FILE (fileváltozó) INTO (változónév); WRITE FILE (fileváltozó) FROM (változónév);
    átviteli utasításokat használhatjuk. ( változónév nem lehet indexes változó vagy egy struktúra komponense, és nem lehet címkeváltozó vagy formális paraméter sem.) A READ/WRITE utasításokban megjelölt változók méretének pontosan meg kell egyezniük a rekord méretével.

    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

    READ FILE (fileváltozó) INTO (változónév) KEY (kulcskifejezés); READ FILE (fileváltozó) INTO (változónév) KEYTO (kulcsváltozó);

    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

    WRITE FILE (fileváltozó) FROM (változónév) KEYFROM(kulcskifejezés);
    utasítást használhatjuk. (Hibát okoz, ha ilyen kulcsú rekord már szerepelt a file-ban.)

    Mind olvasáskor, mind íráskor különféle hibák léphetnek fel (pl. nem létező kulcsú rekord olvasása vagy újraírása, már létező rekord írása stb.). Ezek a hibák egy olyan eseményt váltanak ki, amit ON KEY(fileváltozó) utasításban kezelhetünk le.

    Egyéb

    Megadhatók egyéb módosítók a típushoz, amelyek közül megadok néhányat:

  • A DEFINED kulcsszóval megadható átdefiniálás, melynek segítségével egy memóriaterületen több változó is elhelyezhető.
  • A COMPLEX kulcsszó komplex számot definiál. Alapértelmezett a REAL.
  • Az INITIAL kulcsszóval kezdeti értéket adhatunk meg.
  • Az ALIGNED|UNALIGNED kulcsszóval azt adhatjuk meg, hogy szóhatárra igazítsa-e a változót a fordító. A módosítók kiemelhetők zárójelezéssel.
  •