Sunteți pe pagina 1din 12

UNELE ASPECTE TEHNICE

REFERITOARE LA PRELUCRAREA
FIIERELOR

nelegerea corect a mecanismelor referitoare la prelucrarea fiierelor necesit


cunoaterea unor detalii tehnice de realizare a operaiilor de I/E. Cteva din ele sunt
prezentate n continuare, altele n anexa 3.

9.1 Realizarea fizic a transferului de date


Procedurile i funciile de I/E asigur, prin intermediul DOS, trecerea dintre
nivelul logic, specific utilizatorului, care consider fiierul ca o succesiune de articole
(blocuri, linii, cmpuri) i nivelul fizic de organizare a datelor, n raport cu care fiierul
apare ca o succesiune de octei. n suportul extern magnetic (disc), nregistrarea datelor
se face pe numr ntreg de sectoare. Sub sistemul de operare MS-DOS, sectorul are 512
octei i reprezint unitatea de transfer cu memoria principal. Fiecrui fiier i sunt
alocate dou tipuri de zone de memorie intern: zon utilizator i zon tampon.
Zona utilizator este descris n VAR sau CONST. La ea are acces programul
utilizatorului. Zon are semnificaii diferite, n funcie de tipul fiierului care se
prelucreaz. Ea este fie un articol (la fiiere cu tip), fie un bloc (la fiiere fr tip), fie este
o mulime de zone independente care sunt specificate n operaiile de citire/scriere (la
fiierele TEXT).
Zona tampon (buffer) reprezint zon de memorie principal n/din care se face
transferul datelor din/n exterior i are, sub MS-DOS, 528 octei. Un sistem poate lucra la
un moment dat cu mai multe buffer-e, numrul lor fiind stabilit la configurarea
sistemului (comanda BUFFERS din MS-DOS). Cu ct numrul de buffere este mai
mare cu att crete viteza de transfer, dar i memoria intern ocupat. La citiri succesive,
sectoarele sunt ncrcate n buffere "eliberate" i de aici n zonele utilizator. Dac, de
exemplu, se citete un articol de 120 octei, sistemul citete n buffer un sector ntreg i
mut, de aici, n zon utilizator, 120 octei. La urmtoarea citire, sistemul va utiliza alt

Programarea calculatoarelor Tehnica programrii n limbajul Pascal

buffer etc., astfel nct, la un moment dat, buffer-ele vor conine cele mai recente date
citite. Dac citirea se face aleator (nu secvenial), se ncarc n buffer(e)
sectorul/sectoarele (ca ntregi) care conin(e) articolul. Dac articolul este deja n
buffer(e), nu are loc transfer din exterior ci numai din buffer(e) n zon utilizator.
Succesiunea de principiu a operaiilor, n cazul unui flux general de date care
implic un singur buffer, este prezentat n figura 9.1. Ea este urmtoarea:
1. citirea unui sector din fiierul de intrare n zon tampon asociat;
2. transferul datelor din buffer n zon utilizator asociat fiierului de intrare;
3. pregtirea coninutului zonei utilizatorului asociat fiierului de ieire, pe baza
datelor preluate din zona fiierului de intrare sau din alte surse.

Fig.9.1 - Fluxul general de date n operaiile de I/E


n limbajul PASCAL, aceeai zon utilizator poate fi folosit att pentru fiierul
de intrare, ct i pentru cel de ieire;
4. Transferul datelor din zona utilizator n buffer-ul fiierului de ieire;
5. Scrierea n fiierul de ieire a sectorului (cnd este completat), din zona
tampon.
Cu toate c procesul de trecere dintre nivelurile fizic i logic are trsturi
principale comune, exist deosebiri eseniale de realizare pentru fiierele TEXT i cele
binare. Pentru fiierele binare (cu tip i fr tip) se poate considera valabil schema de
principiu din figura 9.1. Transferul intern dintre buffer i zon utilizator (operaiile 2 i 4)
are loc fr conversii, iar operaiile de intrare/ieire dintr-un program pot avea loc pe
acelai fiier. Pentru fiierele TEXT, o prima particularitate const n aceea c datele
sunt transferate n/din una sau mai multe zone de memorie independente i neomogene
ca tip (figura 9.2).

Unele aspecte tehnice referitoare la prelucrarea fiierelor

Fig.9.2 - Principiul transferului datelor n cazul fiierelor TEXT

n plus, datele sunt "decupate" din zona buffer n zonele de date, pe baza unor
caractere cu rol de separator sau dup alte reguli. Pentru datele numerice (ntregi i
reale), transferul din/n zonele buffer n/din zonele de date (operaiile 2 i 4 din figura
9.2) are loc cu conversie. Acelai lucru se ntmpl la scriere i cu datele de tip
BOOLEAN.
Att pentru fiierele binare ct i pentru cele TEXT, operaiile de transfer din
exterior n buffer (1) i din acesta n zona utilizator (2) au loc, de regul, ca urmare a
execuiei procedurilor de citire. n unele situaii, operaia (1) are loc ca urmare a
execuiei funciilor de testare a sfritului de fiier. Operaiile de transfer din zona
utilizator n buffer (4) i din acesta n exterior (5) au loc ca urmare a execuiei
procedurilor de scriere.
Operaiile 1 i 2 (respectiv 4 i 5) nu au loc, ntotdeauna, simultan. Operaia 1
are loc numai cnd buffer-ul de intrare este "eliberat", iar operaia 5 are loc numai cnd
buffer-ul de ieire este plin. Procesul se desfoar diferit la fiierele binare i la cele
TEXT.
La fiiere binare buffer-ul de intrare este "eliberat" ca urmare a execuiei
unei operaii de deschidere sau a citirii unui articol/bloc (Read, BlockRead) din fiierul
respectiv.
Exemplu:
9. 1.

RESET(fis); buffer "eliberat"


..................
Read(fis,art); realizeaz operaiile 1 i
figura 9.1 (buffer "eliberat")

din

Programarea calculatoarelor Tehnica programrii n limbajul Pascal

Funcia Eof gsete ntotdeauna buffer-ul "eliberat" (fie c este naintea unui
Read, fie c este dup acesta), ceea ce determin ca funcia s efectueze transferul din
exterior n zon buffer (operaia 1 din figura 9.1). Cnd procedura Read se execut dup
apelul funciei Eof, atunci ea realizeaz numai operaia (2).
Exemplu:
9.2.
WHILE

NOT

Eof(f)

DO

Transfera din
(operaia 1)

BEGIN
Read(F,art);

Transfera
din
(operaia 2)
(* Prelucrare articol *)
END;

fiier

buffer

zon

zon

buffer
articol

Dup testarea sfritului de fiier, funcia Eof nu modific pointerul, acesta


rmnnd pe nceputul buffer-ului. Tentativa de citire a unui articol, cnd Eof(f)=TRUE,
produce eroare de I/E (IOResult diferit de 0).
Buffer-ul de ieire se consider plin la fiecare scriere de articol/bloc. Procedurile
Write i BlockWrite realizeaz ntotdeauna operaiile 4 i 5 din figura 9.1.
La fiierele TEXT buffer-ul de intrare se consider "eliberat" dup execuia
unei operaii de deschidere (implicit sau explicit) sau cnd pointerul avanseaz n
buffer dup sfritul de linie (CR/LF) sau dup marcatorul de sfrit de fiier
(CTRL/Z).
Exemple:
9.3. Se presupun trei variabile a, b, c, de tip numeric i secvena de program:
Read(a); {primul Read din program}
Read(b);
Read(c);

naintea primului Read, buferul de intrare este "eliberat" (datorit deschiderii


implicite). De aceea, Read(a) transfer date din exterior n buffer. Se presupune c au
fost introduse urmatoarele valori:

Unele aspecte tehnice referitoare la prelucrarea fiierelor

Tot procedura Read(a) realizeaz transferul (cu conversie) din buffer n zona a
(a=12). Pointerul se plaseaz n poziia 1. Procedura Read(b) gsete bufferul
"neeliberat", deci nu execut transfer din exterior, ci numai din buffer n zona b (b=300).
Pointerul se plaseaz n poziia 2. Procedura Read(c) gsete buffer-ul "neeliberat", deci
nu execut transfer din exterior, ci analizeaz caracterele din buffer. Cum la citirea
datelor numerice spaiile i caracterele CR/LF sunt ignorate, pointerul avanseaz pn n
poziia 3, cnd buffer-ul devine "eliberat", producndu-se n acest moment o cerere de
transfer din exterior n buffer etc. n concluzie, secvena anterioar realizeaz:
Read(a)
Read(b)
Read(c)

operaiile 1 i 2;
operaia 2;
analiza, operaia 1 etc..

9. 4. Se presupun trei variabile a, b, c de tip numeric i secvena de program:


ReadLn(a) ; {prima citire din program}
ReadLn(b) ;
ReadLn(c) ;

naintea primului ReadLn buffer-ul de intrare este "eliberat" (datorit deschiderii


implicite). De aceea, ReadLn(a) transfer date din exterior n buffer. Se presupune c au
fost introduse urmatoarele valori:

Tot procedura ReadLn(a) transfer (cu conversie) din buffer n zona a (a=12) i
plaseaz pointerul la sfritul liniei (n poziia 1), dup CR/LF.
Procedura ReadLn(b) gsete buffer-ul "eliberat" i provoac cerere de transfer
din exterior etc.
Funcia Eof poate gsi buffer-ul "eliberat" sau "neeliberat". Cnd l gsete
"eliberat" produce un transfer din exterior n buffer, plaseaz pointerul pe nceputul su
i testeaz dac este sfrit de fiier (CTRL/Z). Dac funcia Eof gsete buffer-ul
"neeliberat", testeaz dac pointerul indic sfritul de fiier. Dup testarea sfritului de
fiier, funcia Eof nu modific pointerul .
Eliberarea buffer-ului unui fiier TEXT, cu scrierea coninutului su n suportul
extern, se poate realiza cu procedura Flush(f). F trebuie deschis pentru scriere.
n concluzie, att pentru fiierele binare, ct i pentru cele TEXT, trebuie
reinute urmtoarele observaii importante: nu ntotdeauna operaiile Read, ReadLn,

Programarea calculatoarelor Tehnica programrii n limbajul Pascal

BlockRead produc transfer din exterior n memoria principal. Transferul are loc numai
dac buffer-ul este "eliberat"; funcia Eof realizeaz i operaia de transfer din exterior
n memoria principal. Acest lucru se ntmpl cnd, la execuia funciei, buffer-ul de
intrare este "eliberat".

9.2 Accesul la blocul de informaii despre fiier


Declararea variabilei asociate fiierului, de orice tip, are ca efect rezervarea i
iniializarea parial de ctre compilator a unui bloc de informaii (File Informaion
Block). Unele cmpuri ale blocului primesc valori la execuia procedurii Assign, iar
altele la deschiderea fiierului. Pentru fiecare fiier din program, compilatorul genereaz
cte un FIB. Numele simbolic al blocului coincide cu numele intern asociat fiierului
prin descrierea din seciunea VAR. Informaiile din FIB sunt utilizate, la execuie, de
procedurile i funciile care realizeaz operaii de I/E.
Structura FIB este definit n unit-ul Dos prin dou declaraii de tip: FileRec,
pentru fiierele binare i TextRec, pentru fiierele TEXT.
Tipul FileRec reprezint structura FIB pentru fiiere cu tip i fr tip. El este
definit astfel:
FileRec = RECORD
Handle : WORD;
Mode
: WORD;
RecSize : WORD;
Private : ARRAY[1...16] OF BYTE;
UserData : ARRAY[1...16] OF BYTE;
Name : ARRAY[0...79] OF CHAR;
END;
Tipul TextRec reprezint structura FIB pentru fiierele TEXT. El este
definit astfel:
TextRec = RECORD
Handle
: WORD;
Mode
: WORD;
BufSize
: WORD;
Private
: WORD;
BufPos
: WORD;
BufEnd
: WORD;
BufPtr
: ^TextBuf;

Unele aspecte tehnice referitoare la prelucrarea fiierelor

OpenFunc
: Pointer;
InOutFunc
: Pointer;
FlushFunc
: Pointer;
UserData
: ARRAY[1...16] OF BYTE;
Name
: ARRAY[0...79] OF CHAR;
Buffer
: TextBuf;
Semnificaia principalelor cmpuri este urmtoarea:
Handle este o valoare ntreag care reprezint identificatorul pentru fiiere
deschise. Valorile 1-7 sunt utilizate pentru dispozitivele standard de I/E (intrare, ieire,
auxiliar, imprimant, fiierele n curs de folosire cu comanda PRINT din DOS i de
reea). Fiierele deschise ale utilizatorului au valori pentru handle ncepnd cu 8.
Fiierele nedeschise au handle=0. O valoare handle asociat unui fiier devine
disponibil la nchiderea acestuia.
Exemple:
9.5. Dac ntr-un program se lucreaz simultan cu trei fiiere, valorile handle
asociate sunt 8, 9, 10.
9.6. Dac ntr-un program se lucreaz cu trei fiiere deschise i nchise pe rnd,
fiecare va avea valoarea handle opt.
ntr-un program pot fi deschise simultan maxim 12 fiiere ale utilizatorului
(handle cu valori din intervalul [8, 19]).
Mode indic starea fiierului, care poate fi exprimat i prin urmtoarele
constante definite n unit-ul Dos:
FmClosed = $D7B0 fiier nchis;
FmInput
= $D7B1 fiier deschis pentru citire;
FmOutput = $D7B2 fiier deschis pentru scriere;
FmInOut
= $D7B3 fiier deschis pentru citire/scriere;
Fiierele TEXT pot avea strile FmClosed, FmInput, FmOutput. Fiierele
binare pot avea orice stare (implicit FmClosed sau FmInOut). n unit-ul System este
definit variabila FileMode astfel:
FileMode:BYTE=2
Variabila determin modul de deschidere a fiierelor binare de ctre procedura
Reset. Valorile ei posibile sunt: 0 - fiier FmInput; 1 - fiier FmOutput; 2 - fiier
FmInOut. Variabila are valoarea implicit 2. Atribuirea altei valori are ca efect folosirea
acestui mod de ctre toate apelurile ulterioare ale procedurii Reset.
RecSize indic lungimea articolului (blocului) rezultat din descrierea intern
programului.

Programarea calculatoarelor Tehnica programrii n limbajul Pascal

Name este identificatorul extern al fiierului, aa cum este precizat de procedura Assign.
BufSize reprezint lungimea buffer-ului fiierului TEXT.
BufPos, BufEnd, BufPtr reprezint pointeri folosii n gestiunea buffer-elor
asociate fiierului TEXT.
OpenFunc, InOutFunc, CloseFunc, FlushFunc reprezint adresa
driver-elor pentru deschidere, citire/scriere, nchidere, golire a buffer-ului.
Buffer reprezint zon tampon asociat fiierului (chiar buffer-ul fiierului).
Tipul TextBuf este definit n unit-ul Dos astfel: TextBuf = ARRAY[0...127] of CHAR.
Pentru a avea acces la informaiile din FIB, trebuie declarat o variabil de tip
FileRec (respectiv TextRec) care s aib aceeai adres cu FIB-ul (cu variabila de tip
fiier):
a) Pentru fiiere TEXT:
VAR
f: TEXT; inf_f: TextRec ABSOLUTE f;
b) Pentru fiiere cu tip:
VAR
f: FILE OF tip; inf_f: FileRec ABSOLUTE f;
c) Pentru fiiere fr tip:
VAR
f: FILE; inf_f:FileRec ABSOLUTE f;
Cmpurile zonei inf_f se adreseaz cu denumirile lor din definirea articolului
FileRec, respectiv TextRec, din unit-ul Dos.

9.3 Variabile i funcii pentru prelucrarea erorilor de I/E


n fiecare dintre unit-urile standard sunt definite variabile i funcii care pot
semnala modul de desfurare a operaiilor de intrare/ieire.
n unit-ul System sunt definite urmtoarele variabile i funcii:
Variabila InOutRes conine codurile de eroare la execuie, generate de rutinele
de I/E, corespunznd unor situaii cum sunt (anexa 3): eroare la citire de pe disc (codul
100), la scriere pe disc (101), fiier neasignat (102), fiier nedeschis (103), fiier
nedeschis pentru intrare (104), fiier nedeschis pentru ieire (105), format numeric
invalid (106). Variabila InOutRes are valoarea zero dac operaia de I/E s-a desfurat
normal. Ea este definit astfel: InOutRes:Integer=0;
Funcia IOResult returneaz programului valoarea variabilei InOutRes i o

Unele aspecte tehnice referitoare la prelucrarea fiierelor

pune pe aceasta pe zero. Dac valoarea InOutRes este diferit de zero i directiva de
compilare $I are valoarea {$I-}, programul nu se ntrerupe, dar urmtoarea operaie de
I/E nu se va mai executa; dac are valoarea {$I+} programul se oprete cu eroare de
execuie. De aceea, dac se dorete controlul desfurrii unei operaii de I/E, se
procedeaz astfel (pe exemplul procedurii READ):
{$I-}
{inhib ntreruperea programului}
Read (f,zon);
{$I+}
{autorizeaz execuia urmatoarei operaii de I/E}
IF IOResult <>0
THEN
{eroare de I/E} ELSE {nu exist eroare de I/E};
Variabila ErrorAddr conine adresa unde s-a produs eroarea de execuie. n
cazul inexistenei erorii, conine valoarea nil. Variabila este definit astfel:
ErrorAddr:pointer=nil. Adresa este memorat sub forma ssss:dddd, unde ssss este
adresa segmentului de cod, iar dddd este offset-ul (deplasarea n cadrul segmentului).
n unit-ul Dos sunt definite urmtoarele proceduri i variabile:
Variabila DosError, de tip INTEGER, este iniializat de funciile i procedurile din acest unit, cu urmtoarele valori principale (vezi anexa 1):
0
- fr eroare;
2
- fiier negsit;
3
- cale negsit;
4
- prea multe fiiere deschise;
5
- acces interzis; etc.
Variabila DosError are valoarea zero cnd execuia functiilor i a procedurilor
definite n unit-ul Dos se termin normal.
Procedura SetVerify poziioneaz comutatorul verify din DOS. Comutatorul
are dou valori posibile: ON (valoare logic TRUE) sau OFF (valoare logic FALSE).
Cnd comutatorul are valoarea ON, sistemul de operare face verificare dup fiecare
operaie de scriere n fiiere (se verific dac datele scrise pot fi citite fr eroare). Poziia
On a comutatorului verify mrete timpul de execuie a programelor. Cnd comutatorul
are valoarea OFF, sistemul de operare nu face verificarea scrierii. Valoarea implicit a
comutatorului este OFF. Valoarea comutatorului rmne activ pn la o nou setare.
Procedura este defint astfel:
SetVerify(v:Boolean)
V este o variabil de tip BOOLEAN. Cnd v are valoarea TRUE, comutatorul
verify primete valoarea ON. n caz contrar primete valoarea OFF. Procedura are efect
similar cu comanda VERIFY din DOS. Dac comutatorul verify este ON, rezultatul
verificrii scrierii este memorat n variabila DosError.
n anexa 3 sunt prezentate principalele erori de execuie, care includ i pe cele
de intrare/ieire.

Programarea calculatoarelor Tehnica programrii n limbajul Pascal

9.4 Anomalii n tratarea lungimii articolelor (blocurilor)


fiierelor binare
Deoarece peste un fiier fizic poate fi suprapus orice tip de fiier, rmne n
sarcina programatorului s asigure compatibilitatea cu cerinele de prelucrare. n cazul
fiierelor binare, lungimea i structura articolelor (blocurilor) pot diferi ntre momentul
crerii i cel al exploatrii.
Exemplu:
9.7. La momentul crerii, o matrice este scris cte o linie pe articol:
TYPE
a=ARRAY[1..10] of REAL;
VAR
Fis:FILE OF a;
Linie:a;
.....................
BEGIN
Assign(Fis,'MATRICE.DAT');
Rewrite(Fis);
.....................
Write(Fis,Linie);
.....................

La momentul exploatrii, matricea poate fi citit cte un element pe articol:


VAR
Fis:FILE OF REAL;
Element:REAL;
.....................
BEGIN
Assign(Fis,'MATRICE.DAT');
Reset(Fis);
.....................
Read(Fis,Element);
.....................

Fie lart i lbloc lungimea articolelor, respectiv blocurilor unui fiier binar care
are lungimea lfis, exprimat n octei. O prelucrare corect a fiierului presupune s fie
ndeplinite urmtoarele condiii: lfis MOD lart=0, respectiv lfis MOD lbloc=0.
n caz contrar se produc anomalii n prelucrare, ultimii lfis MOD lart, respectiv
lfis MOD lbloc octei, neputnd fi prelucrai.
Exemplu:
9.8. n programul demonstrativ care urmeaz se creeaz fiierul TEST.DAT care
are lungimea 8 octei (se scriu patru articole de cte doi octei). Fiierul este exploatat cu

Unele aspecte tehnice referitoare la prelucrarea fiierelor

articole de 6 octei (REAL), FileSize(f2) returnnd valoarea 1 (8 DIV 6). Prima citire din
fiier transfer primii 6 octei. A doua citire produce eroare de I/E
(8 MOD 6 = 2).
PROGRAM Ex8A;
VAR
f1:FILE OF WORD;
x:WORD;
f2:FILE OF REAL;
y:REAL;
BEGIN
Assign(f1,'TEST.DAT'); Rewrite(f1);
x:=0;
Write(f1,x,x,x,x);
Close(f1);
Assign(f2,'TEST.DAT'); Reset(f2);
Writeln(FileSize(f2));
Read(f2,y);
Read(f2,y); {Error 100: Disk read error}
Close(f2);
END.

Este interesant de analizat i modul n care lucreaz funcia Eof(f), n situaia


fiierului anterior. Dac, dup prima citire (6 octei), se apeleaz funcia Eof(f2), aceasta
returneaz valoarea FALSE (programul de mai jos afieaz textul FALSE), cu toate c
pointerul este pe articolul cu numrul relativ FileSize(f2) (FileSize(f2)=
=lfis DIV lart = 1).
PROGRAM EX8B;
VAR
f1:FILE OF WORD;
x:WORD;
f2:FILE OF REAL;
y:REAl;
BEGIN
Assign(f1,'TEST.DAT'); Rewrite(f1);
x:=0;
Write(f1,x,x,x,x);
Close(f1);
Assign(f2,'TEST.DAT'); Reset(f2);
Read(f2,y);
IF Eof(f2)
THEN BEGIN Writeln('TRUE'); Readln END
ELSE BEGIN Writeln('FALSE'); Readln END;
Close(f2);
END.

Din exemplul anterior se desprinde concluzia c funcia Eof(f) returneaz


valoarea TRUE dac pointerul este plasat dup lfis octei fa de nceputul fiierului.
Cnd nu se produce anomalie de lungime, afirmaia anterioar coincide cu faptul c
Eof(f) returneaz valoarea TRUE cnd pointerul este pe articolul cu numrul relativ
FileSize(f) (FileSize(f)*lart = lfis). De fapt, n cazul anomaliei de lungime, funcia

Programarea calculatoarelor Tehnica programrii n limbajul Pascal

Eof(f) nu poate returna niciodat valoarea TRUE, deoarece "articolul scurt" nu poate
fi niciodat citit. Din cele prezentate anterior, rezult c, n cazul prelucrrii unui
fiier cu structur necunoscut, este recomandabil s se lucreze cu articole de tip
CHAR sau cu blocuri de lungime unu.

S-ar putea să vă placă și