I FILES IN
TURBO PASCAL
Occorre definire:
1) Struttura di tipo [Record].
2) Variabile di tipo [File di Record] (caratterizza il nome logico del file).
3) Variabile di tipo [String]
(caratterizzante il nome fisico del file).
4)
Variabile
di tipo [Record] (caratterizza
la variabile “buffer” attraverso la quale e’ possibile scambiare le
informazioni tra la memoria ed il file di record. La struttura record di tale variabile deve essere identica alla
struttura record del file).
Esempio di definizione delle strutture e delle
variabili:
type
scheda =
record
cognome: string [30]
nome: string [30]
indirizzo: string [30]
end;
Var
FILELOG = file of scheda; (*nome logico del file*)
FILEFIS:
string [12]; (*nome
fisico del file*)
RECSCHEDA: scheda; (*buffer per lo scambio del record tra
RAM e file*)
Operazioni sui files:
ASSIGN ( FILELOG, FILEFIS);
REWRITE ( FILELOG);
RESET ( FILELOG );
READ ( FILELOG, RECSCHEDA );
WRITE ( FILELOG, RECSCHEDA );
SEAK ( FILELOG, NREC );
CLOSE ( FILELOG );
ERASE ( FILELOG );
EOF ( FILELOG );
FILEPOS ( FILELOG );
FILESIZE ( FILELOG );
SEEK ( FILELOG, FILESIZE (FILELOG));
ASSING (
FILELOG, FILEFIS);
Associa a FILEFIS
caratterizzante il nome fisico del file il nome logico FILELOG.
REWRITE ( FILELOG);
CREA
fisicamente un nuovo file e sposta i puntatori EOF e Puntatore
corrente in testa al file.
Se il file non esiste [ viene creato
il file] vuoto.
Se il file già esiste [ viene
cancellato il file esistente e ricreato vuoto.
RESET ( FILELOG);
APRE il file se già esistente e porta il puntatore corrente
all’inizio del file mente l’EOF viene posizionato alla fine del file ovvero
dopo tutti i record in esso contenuti.
Se il file non esiste non viene creato alcun file ed il T.P. ritorna con una segnalazione di ERRORE.
READ (FILELOG,
RECSCHEDA );
Viene letto il file di record FILELOG ed in particolare il record
puntato dal puntatore corrente. Il contenuto di tale record viene trasferito
nel record di appoggio RECSCHEDA. Quindi viene spostato il puntatore corrente
sul record successivo del file. Se il
record teste’ letto e’ l’ultimo del file lo spostamento del puntatore corrente
in avanti provoca il settaggio della variabile di ambiente EOF a true in modo
che il programmatore testando opportunamente tale variabile possa sapere di
essere arrivato alla fine del file.
WRITE (FILELOG,
RECSCHEDA);
Il contenuto del record RECSCHEDA viene trasferito nel file di
record FILELOG sul record puntato dal puntatore corrente. Quindi viene spostato il puntatore corrente
sul record successivo del file. Se il
record teste’ scritto e’ l’ultimo del file viene spostato in avanti anche il
puntatore EOF.
SEEK (FILELOG,
NREC);
Il puntatore
corrente viene spostato all’inizio del record individuato da NREC (NREC e’ una variabile di tipo INTEGER). N.B. Il record 0 è il 1°record del file.
CLOSE ( FILELOG );
Si effettua la chiusura del file ovvero viene
scaricato il buffer di I/O anche se questi non e’ pieno. Viene quindi
aggiornata la FAT.
ERASE (FILELOG);
Viene cancellato fisicamente il file individuato da FILELOG.
EOF (FILELOG);
TRATTASI di una FUNZIONE BOOLEANA.
Restituisce lo status del
puntatore corrente. Viene settata automaticamente dal sistema dopo una
operazione di READ e/o WRITE.
EOF vale: TRUE se dopo l’operazione di I/O si è raggiunto
l’ EOF
EOF vale: False se dopo
l’operazione di I/O non si è raggiunto
l’EOF
FILEPOS (FILELOG);
TRATTASI di una FUNZIONE INTERA. Restituisce il numero del
record su cui è posizionato il puntatore corrente.
FILESIZE (FILELOG);
TRATTASI di una FUNZIONE INTERA. Restituisce il numero dei record che compongono il file.
SEEK ( FILELOG,
FILESIZE (FILELOG));
Trattati di un utilizzo avanzato della istruzione SEEK. In
particolare viene spostato il puntatore corrente sul file di Record FILELOG in
posizione FILESIZE (FILELOG) dove FILESIZE (FILELOG) identifica l’ultimo record
del file. In altre parole viene spostato il puntatore corrente sull’ultimo
record del file di record FILELOG. Questa istruzione deve essere utilizzata
quando si vogliono accodare record ad un file di record gia’ esistente e quindi
aperto con la RESET.
ALTRI TIPI
DI FILES.
Oltre ai files
di record possono esistere files di tipo:
char, boolean, integer, real, text.
Il file e’
costituito da una successione di char. Viene scritto e letto sul file un char
alla volta.
FILES di
TIPO integer.
Il file e’
costituito da una successione di interi. Viene scritto e letto sul file un
integer alla volta.
FILES di
TIPO real.
Il file e’
costituito da una successione di real. Viene scritto e letto sul file un real
alla volta
FILES di TIPO TEXT.
Il file e’ costituito da una successione di sequenze di caratteri
editabili. La separazione tra una
sequenze e l’altra è data da CR+LF. La fine del file è identificata da
CR+LF+EOF
CR ------ ^ M ------- ASCII (13)
LF ------- ^ L ------- ASCII(10)
EOF
------ ^ Z ------- ASCII(26)
Il carattere di controllo ^Z può essere inserito via software o
meno in quanto il TP alla chiusura del file provvede automaticamente ad inserirlo.
I caratteri di controllo CR+LF vengono inseriti automaticamente dal
TP dopo ogni WRITELN. Se si utilizza la
WRITE per scrivere record sul file i caratteri di controllo CR+LF non vengono
inseriti
DIFFERENZA
TRA READ e READLN NELLA LETTURA DI FILES DI RECORD.
READ Legge
l’oggetto definito nella variabile del file a partire dalla posizione del puntatore corrente senza che questi
passi alla sequenza successiva.
READLN Legge l’oggetto
definito nella variabile del file e fa avanzare il puntatore all’oggetto
successivo ignorando tutte le altre informazioni presenti nella linea stessa.
EOF(nomefilelogico) Trattasi di una funzione. EOF ritorna torna .T. se il puntatore è alla
fine del file.
EOLN(nomefilelogico) Trattasi di una funzione. EOLN ritorna
.T. se il puntatore è alla fine della linea. N.B. se
EOF=.T. anche EOLN=.T.
SEEKEOF(nomefilelogico) Si saltano gli spazi e/o le tabulazioni
prima di controllare la fine del
file. Trattasi di una funzione. SEEKEOF
ritorna torna .T. se il puntatore è alla fine del file.
SEEKEOLN(nomefilelogico) Si saltano gli spazi e/o le tabulazioni
prima di controllare la fine della
linea. Trattasi di una funzione.
SEEKEOLN ritorna torna .T. se il puntatore è alla fine del file.
ESEMPIO I
Scrivere (n)
righe su un file di testo dopo averlo creato nuovo. Completato il caricamento
rileggere tutto il file e stampare tutte le righe lette.
Program f1
Var
Nomeflog:
file of text;
Linea:
string [ 255 ];
I:
Integer;
Begin
Assign (nomeflog, “ARCHIV.DAT”);
/* genero il file nuovo */
Rewrite
(nomeflog);
/* scrivo n righe di testo
sul file */
Writeln (nomeflog, “IERI ERA UNA BELLA
GIORNATA”);
Writeln (nomeflog, “OGGI E’ UNA BELLA
GIORNATA”);
......................................................
Writeln (nomeflog, “DOMANI SARA’ UNA
BELLA GIORNATA”);
Close (nomeflog);
/* apro il file
posizionando il puntatore di lettura in testa al file */
Reset(nomeflog);
/* leggo e stampo in
sequenza tutte le righe del file */
While not eof
(nomeflog);
Begin
Readln(nomeflog,linea);
Writeln(linea);
End;
Close
(nomeflog);
End.
Esempio II
Definire un
file di record avente come struttura record i seguenti campi “cod_rec” e “descrizione_record”. Creare il
file nuovo e scriverci (n) record. Effettuare quindi da tastiera l’imput di un valore ed assegnarlo
alla variabile “codice”. Ricercare quindi sul file di record l’eventuale
presenza di un record avente il valore contenuto in “codice” = al valore contenuto
in “cod_rec”. Visualizzare come risultato della ricerca la dicitura “Non
Trovato” se non si riesce a trovare il record desiderato sul file, visualizzare
nel caso di record trovato il corrispondente valore contenuto in
“descrizione_record”. LEGGERE IL FILE SEQUENZIALMENTE AVENDO CURA DI ARRESTARE
LA RICERCA SEQUENZIALE NON APPENA IL RECORD VIENE TROVATO. Utilizzare la
tecnica della programmazione strutturata.
Program f2
Type scheda =
record
Cod_rec :
string[10];
Descrizione_record
: string [ 100 ];
end;
Var
nomeflog
: file of scheda;
Buffer :
scheda;
flag: Boolean;
codice : string[10];
Descrizione :
string [ 100 ];
Procedure
Genera_file;
Begin
/* genero il file nuovo */
Rewrite (nomeflog);
/* scrivo (99) record sul
file di record */
for I = 1 to 99
begin
buffer.cod_rec
:= ord(i):
while
len (buffer.cod_rec) < 10 then
buffer.cor_rec := “0” + buffer.cod_rec:
buffer.descrizione_rec:= “record numero”
+ “ “ + buffer.cod_rec;
Writeln
(nomeflog, buffer);
end;
Close
(nomeflog);
End;
Procedure
ricerca_record;
Begin
/* apro il file
posizionando il puntatore di lettura in testa al file */
Reset(nomeflog);
flag := false;
While not
eof (nomeflog) and flag = false;
Begin
Readln
(nomeflog, buffer);
If
codice = buffer.cod_rec then
Begin
Flag = True;
Descrizione := descrizione.rec”
End;
Close
(nomeflog);
End;
/* main
program */
Begin
/* assegno il nome fisico del file al nome logico */
Assign
(nomeflog, “ARCHIV.DAT”);
/* chiamo la procedura per generare il file */
Genera_file;
/* accetto il valore da
ricercare nel file */
Readln (codice);
/* chiamo la procedura per ricercare sul file */
Ricerca_record;
If flag = “true”
then
Writeln
(descrizione)
Else
Writeln(“record
non trovato”;
End.
Esempio III
Definire un
file di record avente come struttura record i seguenti campi “cod_rec” e “descrizione_record”. Creare il
file nuovo e scriverci (n) record.
Effettuare quindi da tastiera l’imput di un valore ed assegnarlo alla
variabile “codice”. Ricercare quindi sul file di record l’eventuale presenza di
un record avente il valore contenuto in “codice” = al valore contenuto in
“cod_rec”. Visualizzare come risultato della ricerca la dicitura “Non Trovato”
se non si riesce a trovare il record desiderato sul file, visualizzare nel caso
di record trovato il corrispondente valore contenuto in “descrizione_record”.
EFFETTUARE UNA RICERCA SUL FILE IN MODO DICOTOMICO SECONDO IL CAMPO COD_REC.
Effettuare se necessario il preventivo ordinamento del file affinche’ risulti
ordinato in modo crescente secondo il campo cod_rec. ARRESTARE LA RICERCA NON
APPENA IL RECORD VIENE TROVATO. Utilizzare la tecnica della programmazione
strutturata.
Program f3
Type scheda =
record
Cod_rec :
string[10];
Descrizione_record
: string [ 100 ];
end;
Var
nomeflog
: file of scheda;
Buffer :
scheda;
flag:
Boolean;
codice :
string[10];
Descrizione : string [ 100 ];
tabscheda :
array [1..1000] of scheda;
kmax,k,i,j : integer;
posiz, posiz_iniziale,
posiz_finale : integer;
Procedure
scambio;
Begin
Buffer.cod_rec := tabscheda[i].cod_rec;
tabscheda[i].cod_rec := tabscheda[j].cod_rec;
tabscheda[j].cod_rec := Buffer.cod_rec;
Buffer.descrixione_rec :=
tabscheda[i].descrizione_rec;
tabscheda[i].descrizione_rec
:= tabscheda[j].descrizione_rec;
tabscheda[j].descrizione_rec
:= Buffer.descrizione_rec;
End;
Procedure
Genera_file;
Begin
/* genero il file nuovo */
Rewrite (nomeflog);
/* scrivo (99) record sul
file di record */
for I = 1 to 99
begin
buffer.cod_rec
:= ord(i):
while
len (buffer.cod_rec) < 10 then
buffer.cor_rec := “0” + buffer.cod_rec:
buffer.descrizione_rec:= “record numero”
+ “ “ + buffer.cod_rec;
Writeln
(nomeflog, buffer);
end;
Close
(nomeflog);
End;
Procedure
trasfer_file_tabella;
Begin
/* apro il file
posizionando il puntatore di lettura in testa al file */
Reset(nomeflog);
K:=0;
While not
eof (nomeflog)
Begin
K:=
K+1;
Readln (nomeflog, tabscheda[k]);
End;
Kmax := k
Close
(nomeflog);
End;
Procedure
ordina_tabella;
Begin
For i = 1 to
kmax-1 do
Begin
For
j= I+1 to kmax do
begin
If tabscheda[i].cod_rec > tabscheda [j].cod_rec the scambio;
end;
end;
end;
Procedure
trasfer_tabella_file;
Begin
/* apro il file creandolo
di nuovo ovvero cancellando tutto il suo contenuto */
Rewrite(nomeflog);
For K=1
to kmax;
Begin
Writeln
(nomeflog, tabscheda[k];
End;
Close (nomeflog);
End;
Procedure
ordina_file;
Begin
Trasfer_file_tabella;
ordina_tabella;
traasfer_tabella_file;
end;
Procedure
ricerca_record;
Begin
/* apro il file
posizionando il puntatore di lettura in testa al file */
Reset(nomeflog);
Posiz_iniziale :=1:
posiz_finale :=kmax;
Flag:= false;
fine_ricerca:=false
repeat
if posiz_iniziale=posiz_finale
then
begin
posiz=posiz_iniziale;
fine_ricerca:=true;
end
else
begin
Posiz := (posiz_iniziale – 1) + int( (posiz_finale + 1 –posiz_iniziale) /
2);
end;
Seek
(nomeflog, posiz);
Readln
(nomeflog,buffer);
If
codice = buffer.cod_rec then
Begin
Flag:
= True;
fine_ricerca:=true;
Descrizione := descrizione.rec”
End;
Else
Begin
If
codice > buffer.cod_rec then
begin
Posiz_iniziale := posiz+ 1;
end
else
begin
posiz_finale := posiz – 1;
until flag = true
or fine_ricerca=true
Close
(nomeflog);
End;
/* main
program */
Begin
/* assegno il nome fisico del file al nome logico */
Assign (nomeflog, “ARCHIV.DAT”);
/* chiamo la procedura per generare il file */
Genera_file;
/* chiamo la procedura per ordinare il file */
ordina_file;
/* accetto il valore da
ricercare nel file */
Readln (codice);
/* chiamo la procedura per ricercare sul file */
ricerca_record;
If flag = “true”
then
Writeln
(descrizione)
Else
Writeln(“record
non trovato”);
End.
Esempio IV
Definire un
file di record avente come struttura record i seguenti campi:
“codice”
string (6)
“classe” string (4)
“Alunno” string (40)
“Indirizzo” string (40)
“Importo_versato” real
Supporre il
file già esistente, non vuoto ed ordinato secondo i campi “Classe” + “Alunno”.
Leggere tutto il file e stampare i vari record via
via che questi vengono letti. Stampare tutti i campi di ogni record letti
avendo cura di allineare verticalmente i campi corrispondenti di ciascun
record. Effettuare un salto pagina del foglio al variare della classe (rottura
di classe).
Considerando
che di norma non si hanno classi superiori a 30 alunni, considerando che il
foglio di stampa o meglio la stampante ad aghi sia impostata per 66 righe
(foglio di lunghezza 11” e densità di
scrittura verticale di 6 linee per pollice) su ogni foglio si avranno tutti gli
alunni di una classe stampati ordinati per cognome. Non esiste quindi il caso
che alunni di una stasse classe vengano stampati su de fogli consecutivi per
cui e’ inutile effettuare controlli di questo tipo onde evitare che un alunno
venga stampato sulla linea di perforazione orizzontale tra due fogli contigui.
Completata la
stampa degli alunni di una classe prima di saltare al foglio successivo
stampare un rigo aggiuntivo con indicato il totale dell’importo versata a
livello di classe dagli alunni di quella classe.
Completata la
stampa di tutte le classi (se si hanno 60 classi nella scuola si saranno
stampati 60 fogli) stampare su un foglio successivo il totale riepilogativo di
quanto e’ stata versato da tutti gli alunni a livello di istituto.
Ipotizzare
per il report di stampa relativo al foglio di classe una struttura di questo
tipo:
classe alunno Indirizzo codice importo versato
xxxx
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxx xxxxx,xx
xxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxx xxxxx,xx
xxxx
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxx xxxxx,xx
……. …………………… ………………………… ………. …………
xxxx
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxx xxxxx,xx
--------------------------------------------------
Totale versato dalla classe:
--------- xxxxxx,xx
Ipotizzare
per il report di stampa relativo al totale versato a livello di istituto una
struttura di questo tipo:
Totale versato dall’istituto:
-------- xxxxxx,xx
Program f4
Type scheda =
record
Codice: string (6)
Classe: string (4)
Alunno: string (40)
Indirizzo: string (40)
“Importo_versato: real
end;
Var
nomeflog
: file of scheda;
Buffer :
scheda;
primavolta:
Boolean;
classe-alunno-pre: string[44];
classe-alunno-cor: string[44];
Tot-classe: real;
Tot-istituto
real;
Riga:
string (80);
Function
RiempiStrToStr (stringainput, sizemax) : string;
/* La procedura
accoda alla stringa passata (stringainput) tanti (blank) a dx */
/* fino al
raggiungimento di una lunghezza pari al valore di (sizemax) */
Var
Stringainput
: string
Sizemax :
integer;
K:
integer;
Begin
If
lengtht (stringainput) < sizemax then
begin
For
k = 1 to (sizemax – length (stringainput))
Begin
stringainput
:= stringainput = “ “;
end;
end
else
begin
stringainput := midstr (stringainput, 1,
sizemax):
end;
RiempiStrToStr
:= stringainput;
end;
Function RiempiNumToStr (Numeroinput, sizemax,
Numerodecimali) : string;
/* La procedura
trasforma il numero passato (Numeroinput) in stringa */
/* lo allinea a
dx in un campo lungo (sizemax) */
/* inserisce un
numero di decimali fino a (Numero decimali) */
/* inserisce la
(virgola) di separazione tra la parte intera e quella decimale */
/* inserice il
(punto) quale separazione nella parte intera tra le migliaia) */
/* inserisce
tanti (blank) a sx affinché la stringa
di output sia lunga (sizemax) */
Var
Stringaotput :
string
Numeroinput :
real;
Sizemax : integer;
K:
integer;
*********** da completare
**************
*********** da fare per compito **************
Begin
Numeroinput
:= Rounded (Numeroinput, Numerodecimali);
Stringaoutput
:= FloatToStr (Numeroinput)
If
lengtht (stringaoutput) < sizemax then
begin
For
k = 1 to (sizemax – length (stringaoutput))
Begin
stringaoutput
:= “ “ + stringaoutput;
end;
end
else
begin
stringaoutput := “”;
For k
= 1 to sizemax
Begin
stringaoutput
:= stringaoutput + “*”;
end;
end;
RiempiNumToStr := stringaoutput;
end;
Procedure
stampa-testata;
var
testo :string;
begin
testo := “classe alunno Indirizzo “;
testo := testo + “codice
importo versato”;
writeln (lpt1, testo);
end;
Procedure
stampa-corpo;
begin
writeln
(lpt1,riga);
end;
Procedure
stampa-coda;
begin
wirteln (lpt1,
“----------------------------------------------------------“);
writeln
(lpt1, “totale versato dalla
classe ------ “, Tot-classe);
end;
procedure
stampa-totale-versato-da-istituto;
Begin
writeln (lpt1, “totale versato dall’istituto ------
“, Tot-istituto);
end;
procedura
after-page;
Begin
writeln (lpt1,
ASCII (15));
end;
Procedure
prepara-riga-stampa;
Begin
Riga := “”;
Riga := Riga + RiempiStrToStr
(buffer.classe, 4);
Riga := Riga + “ “;
Riga := Riga + RiempiStrToStr (buffer.alunno, 40);
Riga := Riga + “ “;
Riga := Riga + RiempiStrToStr (buffer.indirizzo, 40);
Riga := Riga + “ “;
Riga := Riga + RiempiStrToStr (buffer.codice, 6);
Riga := Riga + “ “;
Riga := Riga + RiempiNumToStr (buffer.importo-versato, 10, 2);
end;
/*
main Program */
Begin
/* assegno il nome fisico del file al nome logico */
Assign (nomeflog, “ARCHIV.DAT”);
/* apro il file */
Reset (nomefllog);
/* reset delle variabili di comodo */
Tot-classe := 0;
Tot_isituto := 0:
classe-alunno-pre := “”;
classe-alunno-cor := “”;
primavolta := .T.;
/* lettura sequenziale del
file */
While not
eof(nomeflog) do
Begin
Read
(nomeflog, buffer);
buffer-classe := riempi (buffer.classe,4);
buffer-alunno := riempi
(buffer-alunno,40);
classe-alunno-cor := buffer.classe +
buffer.alunno;
if
primavolta = .T. then
begin
classe-alunno-pre := classe-alunno-cor;
primavolta := .F.;
stampa-testata;
end;
if classe-alunno-cor <> classe-alunno-pre
then
begin
stampa-coda;
after-page;
stampa-testata;
Tot-classe := 0;
end;
prepara-riga-stampa;
stampa-corpo;
Tot-classe := Tot-classe +
buffer.importo-versato;
Tot-istituto := Tot-istituto +
buffer.importo-versato;
classe-alunno-pre := classe-alunno-cor;
end;
if primavolta
<> .T. then
begin
stampa-coda;
after-page;
stampa-totale-versato-da-istitito;
end;
close (nomeflog);
End.
NOZIONI DI CARATTERE GENERALE SUI FILES
AD INDICE.
I File ad Indice consentono:
-Accesso Sequenziale
-Accesso Random per Key
-Accesso Dinamico (Random e Sequenziale
contemporaneamente)
I File ad Indice sono costituiti da:
-File dei Dati
-File delle chiavi
(tanti file delle key quanti sono gli indici del file)
CONSIDERAZIONI
SUL FILE DELLE KEY.
-La chiave è costituita da un insieme
contiguo di byte del tracciato record del file dati. (certi sistemi operativi
ammettono anche chiavi costituite da più blocchi di byte non contigui fra loro
del file dati).
-La chiave può raggruppare un insieme di
campi del tracciato record del file dati.
-Il file delle chiavi è sempre ordinato
secondo la sua key.
-Generalmente la struttura del file
delle key è ad albero binario bilanciato di tipo B-TREE. (I vari nodi vengono
inseriti sul file delle key con la tecnica MP.S.
-Un file indice di (N) record ha (N)
record sul file dati ed (N) nodi sul file ad Indice.
COMANDI DI S.O. PER CREARE UN FILE
I.S.A.M. MULTIKEY.
Si consideri il
file dati di nome (Nomefiledati) avente il seguente tracciato record:
Campo A |
Campo B |
Campo C |
Campo D |
Campo E |
Campo F |
Si consideri il
file isam costituito da due files delle chiavi (Nomefileindice1 e
Nomefileindice2)
Sia KEY1 la
chiave del file (Nomefileindice1)
Dove KEY1 e’
una stringa costituita dalla unione di due stringhe quali (Campo A) + (Campo B)
Sia KEY2 la
chiave del file (Nomefileindice2)
Dove KEY2 e’
una stringa costituita dalla unione di due stringhe quali (Campo B) + (Campo
C)
I comandi di
sistema operativo per la creazione del file dati e dei due files ad indice
saranno:
CDF Nomefiledati Rsz (nn)
CIF Nomefileindice1 Nomefiledati Ksz(nn1) Kof(nn1) No
duplicate
CIF Nomefileindice2 Nomefiledati Ksz(nn2) Kof(nn2) SI duplicate
Dove:
Nomefiledati……….……..: Nome del file Dati.
NomefiIeindice1………….: Nome del file Indice 1.
Nomefileindice2……..…...: Nome
del file Indice 2.
Rsz (nn) …………….…….: Lunghezza
del record relativo al file dati (Record Size).
Kof (nn1) …………..…….: Byte di
partenza sul file dati per determinare key1 (Key start)
Ksz(nn1) ………………….: Numero di
byte sul file dati caratterizzanti la key1 (Key size)
Kof (nn2) …………..…….: Byte di
partenza sul file dati per determinare key2 (Key start)
Ksz(nn2) ………………….: Numero di
byte sul file dati caratterizzanti la key2 (Key size)
Si duplicate………………...: Si
ammettono duplicati di chiave per il file indice.
No duplicate………..……...: Non si ammettono duplicati di chiave per il
file indice.
COMANDI DI S.O. PER CANCELLARE UN FILE I.S.A.M. MULTIKEY.
DIF Nomefileindice1 (PER CANCELLARE IL FILE INDICE 1)
DIF Nomefileindice2 (PER CANCELLARE IL FILE INDICE 2)
DDF Nomefiledati (PER CANCELLARE IL FILE DATI)
GESTIONE DI
UN FILE I.S.A.M.
IN T.P. CON
LE UTILITY DEL
T.T.BOX.
Osservazioni di
carattere generale.
A)
Il file
I.S.A.M. è costituito da un filedati (NomeFileDati.DAT) e da (N) files indice
(NomeFileIndice_n).
B)
Non
esistono a livello di sistema operativo MSDOS comandi di s.o. per la creazione
di file I.S.A.M. La creazione del file I.S.A.M. va fatta solo a livello
software all’interno del programma utilizzando apposite procedure incluse nella
libreria del T.T.BOX.
C)
E’ sempre
possibile associare ad un file dati (n) files ad Indice.
D)
Non
necessariamente la key del file indice e’ costituita da sottostringhe del
record del file dati. E’ possibile associare tramite algoritmi di
randomizzazione valori numerici a stringhe di caratteri.
E)
E’ sempre
possibile aggiungere al file ISAM un nuovo file delle chiavi intriucendo una
nuova chiave, oppure cancellare un file delle chiavi del file ISAM e/o
modificare la struttura di un file delle chiavi gia’ esistente.
F)
L’accesso
ai vari record del file avviene tramite la chiamata di opportune procedure e/o
funzioni definite nel T.T.BOX.
G)
E’
indispensabile definire in testa al programma Pascal le seguenti costanti:
MAXDATARECSIZE = nn (Massima lunghezza del
record)
MAXKEYLENGHT = mm (Massima
lunghezza della key)
PAGESIZE = kk (Dimensione
della pagina)
ORDER = kk/2
PAGESTACKSIZE = kk/2
MAXHEIGHT = kk/2
PAGESIZE, ORDER, PAGESTACKSIZE e
MAXHEIGHT identificano le dimensioni delle pagine all’interno delle
quali vengono trascritti i vari “nodi” che caratterizzano il file delle chiavi.
Normalmente ORDER=PAGESTACKSIZE=MAXHEIGHT=PAGESIZE/2
Volendo ottimizzare e la ricerca e lo
spazio su disco, il T.T.BOX fornisce delle formule logaritmiche per la determinazione dei valori
ottimali da attribuire a PAGESIZE,
ORDER, PAGESTACKSIZE e MAXHEIGHT.
H)
E’ indispensabile includere nel programma, subito dopo la definizione delle
costanti descritte al punto (G), le
seguenti procedure:
(* $I Access3.box *)
(* $I GetKey.box *)
(* $I AddKey.box *)
(* $I DelKey.box *)
NomeLogicoFileDati: DATAFILE
NomeLogicoFileIndice: INDEXFILE
NomeFisicoFileDati: string (12)
NomeFisicoFileIndice: string (12)
MAKE FILE (NomeLogicoFileDati,NomeFisicoFileDati,Rsz)
Dove:
NomeLogicoFileDati…: nome logico del file dati.
NomeFisicoFileDati…..
: nome fisico del file dati.
Rsz…………………….: record size del file dati (lunghezza del record).
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
MAKEINDEX
(NomeLogicoFileIndice, NomeFisicoFileIndice,Ksz,Dup)
Dove:
NomeLogicoFileIndice….…..: nome logico del file ad indice.
NomeFisicoFileIndice………: nome fisico del file ad indice.
Ksz…………………………: lunghezza della chiave.
Dup…………………………: indicatore esistenza o meno di key doppie
(Dup=1 esistonoduplicati di Key)
(Dup=0 non esistono Key doppie).
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
APERTURA
DEL FILE DATI DI UNA STRUTTUTRA I.S.A.M.
OPENFILE
(NomeLogicoFileDati, NomeFisicoFileDati, Rsz)
Dove:
NomeLogicoFileDati………………: Nome logico del file dati.
NomeFisicoFiledati………………...: Nome fisico del file dati.
Rsz…………………….…………..:
Record size del file dati.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
APERTURA
DEL FILE INDICE IN UNA STRUTTURA I.S.A.M.
OPENINDEX
(NomeLogicoFileIndice,NomeFisicoFileIndice,Ksz,Dup)
Dove:
NomeLogicoFileIndice………………: Nome logico del file ad
indice.
NomeFisicoFileIndice…………….....: Nome fisico del file ad
indice.
Ksz……………………..…….……..: Key size.
Dup………………………………….: Indicatore duplicati
di key.
(Dup=0 NO
DUPLICATE)
(Dup=1 SI DUPLICATE).
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
CANCELLAZIONE
DI UN RECORD DAL FILE DATI.
DELETEREC(NomeLogicoFileDati,Recpos)
Dove:
NomeLogicoFileDati………………: Nome logico del file dati.
Recpos……….……………………: Numero del record da delettare.
Il valore di Recpoc
viene calcolato all’interno della procedura di DELETEKEY.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
CANCELLAZIONE
DI UN NODO DAL FILE DELLE KEY.
DELETEKEY
(NomeLogicoFileIndice,Recpos,Key)
Dove:
NmeLogicoFileIndice…………….: nome logico del file ad indice
Recpos…………………….…….: posizione del record nel file dati
corrispondente alla key
trovata nel file delle chiavi
Key…………………….…… ….: stringa caratterizzante la key del record da
cancellare.
Il valore di
Recpoc viene calcolato all’interno della procedura di DELETEKEY e restituito
affinche’ possa essere passato alla procedura DELETEREC per completare la
cancellazione del record di chiave (key) dal file dati.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione
non riuscita
ADDREC (NomeLogicoFileDati, Recpos, Filerec)
Dove:
NomeLogicoFileDati………:
nome logico del file dati.
Recpos……………………:
posizione del record nel file dati.
Filerec……………………..: variabile di tipo
RECORD caratterizzante la struttura
del record che si vuol
inserire sul file dati.
Il valore di
Recpoc viene calcolato all’interno della procedura di ADDKEY e restituito
affinche’ possa essere passato alla procedura ADDREC per completare
l’inserimento del record di chiave (key) nel file dati.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
ADDKEY
(NomeLogicoFileIndice, Recpos, Key)
Dove:
NomeLogicoFileIndice…….: nome logico del
file ad indice.
Recpos……….: posizione del record nel
file dati.
Key…………...: variabile stringa contenente
la Key del file indice da inserire nel file.
Il valore di
Recpoc viene calcolato all’interno della procedura di ADDKEY e restituito
affinche’ possa essere passato alla procedura ADDREC per completare
l’inserimento del record di chiave (key) nel file dati.
Le routines della
T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
CHIUSURA DI UN FILE DATI IN UNA
STRUTTURA I.S.A.M.
CLOSEFILE (NomeLogicoFileDati)
Dove:
NomeLogicoFileDati
= nome logico del file dati
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione
non riuscita
CHIUSURA DI UN FILE INDICE IN UNA
STRUTTURA I.S.A.M.
CLOSEINDEX (NomeLogicoFileIndice)
Dove
NomeLogicoFileIndice =
nome logico del file ad indice.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
LETTURA DI UN RECORD IN UN FILE DATI.
GETREC
(NomeLogicoFileDati,Recpos,Filerec)
dove :
NomeLogicoFileDati :nome logico del file dati.
Recpos :
posizione del record nel file dati.
Fielrec :
Bufffer nel quale viene trasferito il record letto.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
RICERCA DI UN NODO IN UN FILE DELLE
CHIAVI
(RICERCA PER KEY UGUALI AD UN VALORE PREFISSATO).
FINDKEY (NomeLogicoFileIndice,recpos,key)
dove:
NomeLogicofileIndice : nome logico del file ad indice.
recpos
: posizione del
record corrispondente nel file dati.
Key :
stringa caratterizzante la key per la ricerca del record nel file
ad indice.
Se il file ad
indice ammette dei duplicati di key viene letto il primo record trovato.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
SCRITTURA DI UN RECORD GIA’ ESISTENTE SU
UN FILE DATI.
PUTREC
(NomeLogicoFileDati,Recpos,Filerec)
dove:
NomeLogicoFileDati : nome logico del file dati.
Recpos : posizione del record nel file
dati.
Filerec :
buffer contenente il record da riscrivere nel file.
Le routines della
T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
(RICERCA PER KEY MAGGIORE – UGUALE AD UN VALORE PREFISSATO)
SEARCHKEY(NomeLogicoFileIndice,
Recpos, Key)
Dove:
NomeLogicoFileIndice………………………:
nome logico del file ad indice.
Recpos…………………………..…………:
posizione del record file dati.
Key………………………………..……….:
stringa caratterizzante la key per la ricerca del
record nel file ad indice specificato.
Se ci sono
duplicati di key viene data la posizione del file dati (recpos) relativa al
primo nodo trovato nel file delle key.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
RICERCA DI UN NODO IN UN FILE AD INDICE
(RICERCA PER KEY MAGGIORE AD UN VALORE
SPECIFICATO)
NEXT(NomeLogicoFileIndice, Recpos, Key)
Dove:
NomeLogicoFileIndice………………………:
nome logico del file ad indice.
Recpos…………………………..…………:
posizione del record file dati.
Key………………………………..……….:
stringa caratterizzante la key per la ricerca del
record nel file ad indice specificato.
Se ci sono
duplicati di key viene data la posizione del file dati (recpos) relativa al
primo nodo trovato nel file delle key.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
RICERCA DI UN NODO IN UN FILE AD INDICE
(RICERCA PER KEY MINORE AD UN VALORE
SPECIFICATO)
PREVKEY(NomeLogicoFileIndice,
Recpos, Key)
Dove:
NomeLogicoFileIndice………………………:
nome logico del file ad indice.
Recpos…………………………..…………:
posizione del record file dati.
Key………………………………..……….:
stringa caratterizzante la key per la ricerca del
record nel file ad indice specificato.
Se ci sono
duplicati di key viene data la posizione del file dati (recpos) relativa al
primo nodo trovato nel file delle key.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
POSIZIONAMENTO DEL PUNTATORE ALL’INIZIO
DEL FILE
CLEARKEY
(NomeLogicoFileIndice)
Dove:
NomeLogicoFileIndice = nome logico del
file ad indice.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
CALCOLO DEL
NUMERO DI RECORD ALLOCATI IN UN FILE DATI DI UNA STRUTTURA “I.S.A.M.”
A:= FILELEN
(NomeLogicoFileDati)
Dove:
NomeLogicoFileDati = nome logico del
file dati.
La funzione
FILELEN include, oltre ai record validi, sia i record riservati (record 0), sia
i record delettati.
A:= USEDRECS(NomeLogicoFileDati)
Dove:
NomeLogicoFileDati = nome logico del
file dati.
La funzione
USEDRECS ritorna escludendo nel conteggio i records riservati e/o cancellati.
Le routines
della T.T.BOX utilizzano la variabile globale (OK) di tipo boolean per testare
l’esito dell’operazione (return code).
OK= T. operazione andata a buon fine
OK= F. operazione non riuscita
PROCEDURA PER LA CREZIONE COMPLETA DI UN FILE I.S.A.M.
Procedure CREA_FILE;
Begin
Initindex;
makefile (NomeLogicoFileDati, NomeFisicoFiledati,
34);
if OK then
begin
makeindex (NomeLogicoFileIndice,
NomeFisicoFileIndice, 15,1);
if not OK then
begin
routine_errore;
end;
end
else
begin
routine_errore;
end;
end;
PROCEDURA PER L’APERTURA DI UN FILE I.S.A.M.
Procedure APRI_FILE;
Begin
Initindex;
openfile (NomeLogicoFileDati,
NomeFisicoFileDati, 34);
if OK then
begin
openindex (NomeLogicoFileIndice,
NomeFisicoFileIndice, 15, 1);
begin
routine_errore;
end;
end
else
begin
routine_errore;
end;
end;
PROCEDURA
PER LA CANCELLAZIONE DI UN FILE I.S.A.M.
Procedure CANCELLA_RECORD;
Begin
Deletekey
(NomeLogicoFileIndice, recpos, key);
If
OK then
Begin
Deleterec (NomeLogicoFileDati,recpos);
if
not OK then
begin
routine_errore;
end;
end
else
begin
routine_errore;
end;
chiudifile;
end;
PROCEDURA PER L’INSERIMENTO DI UN RECORD IN UN
FILE I.S.A.M.
Procedure INSERIMENTO;
Begin
apri_file;
accetta_campi_record;
prepara_key;
addrec
(NomeLogicoFileDati,recpos, filrec);
if
OK then
begin
addkey
(NomeLogicoFileIndice, recpos, key);
if
not OK then
begin
routine_errore;
end;
end
else
begin
routine_errore;
end;
chiudi_file;
end;
PROCEDURA PER LA RICERCA DI UN RECORD IN UN FILE I.S.A.M
Procedure RICERCA_RECORD;
Begin
Apri_file;
accetta_key;
findkey (NomeLogicoFileIndice, recpos, key);
if
OK then
begin
getrec(NomeLogicoFileDati, recpos,
filrec);
if
not OK then
begin
routine_errore;
end;
end
else
begin
routine_errore;
end;
chiudi_file;
end;
PROCEDURE PER LA RICERCA E MODIFICA DI UN RECORD IN UN FILE
I.S.A.M.
Procedure MODIFICA_RECORD;
Begin
Apri_file;
accetta_key;
findkey (NomeLogicoFileIndice, recpos, key);
if
OK then
begin
modifica_campi_record;
putrec (NomeLogicoFileDati, recpos, filrec);
if
not OK then
begin
routine_errore;
end;
end
else
begin
routine_errore;
end;
chiudi_file;
end;
PROCEDURE PER LA LETTURA E STAMPA DI UN FILE I.S.A.M.
Prevedere la
possibilità di poter stampare i vari record del file, digitando opportunamente
i valori di (keyini) e (keyfin),
secondo le seguenti casistiche:
dall’inizio
alla fine del file
dall’inizio
ad un determinato record
da un
determinato record alla fine del file
da un
determinato record iniziale ad un determinato record finale
un solo
record (keyini = keyfin)
Procedure LETTURA_STAMPA;
Begin
Apri_file;
flageof
:= .F.;
Repeat
accetta_key_ini;
accetta_key_fin;
until keyini <= keyfin;
/*
posizionamento */
key
:= keyini
searchkey (NomeLogicoFileIndice, recpos, key);
if
OK then
begin
if
key <= keyfin then
begin
getrec
(NomeLogicoFileDati, recpos, filrec);
if
not OK then
begin
routine_errore;
end
else
begin
prepara_riga_stampa;
stampa_riga;
end;
end
else
begin
flageof := .T.;
end;
end
else
begin
routine_errore;
end;
/* lettura sequenziale per chiave*/
while
(flageof = .F.) AND
(OK = .T.) do
begin
nextkey (NomeLogicoFileIndice, recpos, key);
if
OK then
begin
if
key <= keyfin then
begin
getrec
(NomeLogicoFileDati, recpos, filrec);
if
not OK then
begin
routine_errore;
end
else
begin
prepara_riga_stampa;
stampa_riga;
end;
end
else
begin
flageof
:= .T.;
end;
end
else
begin
routine_errore;
end;
end;
chiudi_file;
end;
Procedure ACCETTA_KEYINI;
Begin
Readln
(Keyini);
End;
Procedure ACCETTA_KEYFIN;
Begin
Readln
(Keyfin);
if
keyfin = “” then
begin
keyfin
:= “zzzzzzzzzz”;
end;
End;