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.

 

 

FILES di TIPO char

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.

 

 

 

DIFFERENZA TRA WRITE e WRITELN NELLA SCRITTURA DI FILES DI RECORD.

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 *)

 

  1. Definire la variabile caratterizzante il nome logico del FILE DATI. Considerato che il  T.T.BOX utilizza per definire il “file dati” il tipo di dato (DATAFILE), Supponendo di voler utilizzare cone nome logico del file dati la variabile (NomeLogicoFileDati) si dovrà scrivere:

NomeLogicoFileDati: DATAFILE

 

  1. Definire la variabile caratterizzante il nome logico del FILE INDICE. Considerato che il  T.T.BOX utilizza per definire il “file indice” il tipo di dato (INDEXFILE), Supponendo di voler utilizzare cone nome logico del file indice la variabile (NomeLogicoFileindice) si dovrà scrivere:

NomeLogicoFileIndice: INDEXFILE

 

 

  1. Definire la variabile caratterizzante il nome fisico del FILE DATI come stringa di 12 caratteri, ovvero si dovrà scrivere:

NomeFisicoFileDati:  string (12)

 

  1. Definire la variabile caratterizzante il nome fisico del FILE INDICE come stringa di 12 caratteri, ovvero si dovrà scrivere:

NomeFisicoFileIndice:  string (12)

 

 


 

CREAZIONE DEL FILE DATI

 

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

 

 

 

CREAZIONE DEL FILE AD INDICE

 

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

 

 

INSERIMENTO DI UN RECORD NEL FILE DATI

 

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

 

 

 

 

INSERIMENTO DI UN RECORD NEL FILE DELLE CHIAVI

 

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 DI UN NODO IN UN FILE A INDICE

 (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.

 

FILELEN = Records VALIDI + Records RISERVATI + Records 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;