1
File ad accesso Random
• Random access files
– Per accedere direttamente singoli record senza ‘attraversare’ quelli che li precedono – I dati possono essere inseriti senza distruggere gli altri
– I dati registrati possono essere modificati senza sovrascrivere o cancellare parzialmente quelli esistenti.
– un file sequenziale deve essere riscritto completamente se si vuole modificare qualche informazione in un record
• Tipicamente i record registrati in un file random hanno tutti la stessa lunghezza (in byte)
… considereremo solo questo caso …
0 200 300 400 500
byte offsets
}
} } } } } }
100
100 bytes
100 bytes
100 bytes
100 bytes
100 bytes
100 bytes
Random Access File
– Sono file ‘binari’
• Tutti i dati dello stesso tipo hanno una stessa dimensione in memoria
• Tutti i record dello stesso tipo hanno la stessa lunghezza
• Essendo file binari, i dati registrati non sono adatti per la lettura ‘umana’
– I dati non sono formattati ma sono registrati come "raw bytes"
3
Random Access File
• Operazioni di apertura e chiusura file nel linguaggio C:
… come per i file sequenziali …
Dichiarazione file
FILE *<nome_puntatore_file>
Apertura file :
< nome_puntatore_file > = fopen (“<nomefile>”, <modo_apertura>);
Chiusura file:
fclose(< nome_puntatore_file >);
Random Access File
• Operazioni di apertura e chiusura file:
modi di apertura:
• “w” crea un file per scrivere in esso dei valori (solo scrittura); se il file già esiste esso sarà riscritto cancellando il contenuto precedente
• “r” apre il file in lettura per leggerne il contenuto (solo lettura)
• “a” apre il file per scrivere altri valori alla fine dello stesso
• “w+” crea un file per l’aggiornamento (lettura e scrittura) ; se il file già esiste esso sarà riscritto cancellando il contenuto precedente
• “r+” apre il file in aggiornamento (lettura e scrittura)
• “a+” apre il file per la lettura e l’accodamento (lettura e scrittura), la
scrittura sarà eseguita alla fine del file
5
Random Access File
• Operazioni di scrittura e lettura:
– fwrite – per scrivere un record su un file random – fread – per leggere il contenuto di un file random
Sintassi:
• fwrite( &var_name, sizeof( <type> ), 1, myPtr );
• &var_name– nome della variabile da scrivere sul file (ovvero locazione di memoria da cui trasferire i bytes nel file)
• sizeof( <type> )– dimensione in bytes di var_name in base al suo tipo (ovvero numero di bytes da trasferire nel file)
• 1– nel caso di array indica il numero degli elementi dello array da scrivere nel file (in questo caso un solo elemento). E’ possibile scrivere, in una sola volta, più elementi di un array indicandone il numero nel terzo argomento
• myPtr– puntatore al file su cui scrivere
• fread… sintassi simile
Random Access File
• Per scrivere structs (cioè records)
• fwrite( &myObject, sizeof (<struct myStruct>), 1, myPtr );
– &myObject nome della variabile di tipo struct myStruct da scrivere nel file – sizeof Restituisce la dimensione in bytes dell’elemento indicato tra le parentesi
(lunghezza del record in bytes) – 1 è scritto un solo record per volta – myPtr puntatore al file
7
• fread
– Legge uno specificato numero di bytes da un file random
fread(&myObject, sizeof (<struct myStruct>), 1, myPtr);
– Gli argomenti hanno lo stesso significato del caso fwrite(…)
• fseek
– Per posizionarsi all’interno del file ad uno specifico record – fseek( myPtr, offset, symbolic_constant);
• myPtr – puntatore al file
• offset– indicatore delle posizioni nel file (0 è la prima posizione)
• symbolic_constant– specifica la posizione di lettura nel file
• SEEK_SET– lo offset è calcolato dall’inizio del file
• SEEK_CUR - lo offset è calcolato a partire dalla posizione corrente
• SEEK_END - lo offset è calcolato a partire dalla fine del file
9
#include <stdio.h>
main()
{ struct studente{
int matricola;
char cognome[15];
char nome[10];
float media_voti;
};
int i;
struct studente studenteSannio_vuoto = { 0, " ", " ", 0.0 };
FILE *cfPtr;
cfPtr = fopen("studenti.dat", "w" );
if ( cfPtr == NULL )
printf("Non possibile aprire il file !!.\n" );
else
{for( i = 1; i <= 100; i++ ) // scrive 100 record ‘vuoti’ nel file {studenteSannio_vuoto.matricola=i;
fwrite( &studenteSannio_vuoto,sizeof( struct studente),1,cfPtr );
}
fclose( cfPtr );
}
printf("FINE PROGRAMMA");
}
Random Access File
Programma esempio Creazione di un file random inizializzandolo in modo sequenziale
#include <stdio.h>
main() {
struct studente{
int matricola;
char cognome[15];
char nome[10];
float media_voti;
};
FILE *cfPtr;
struct studente studenteSannio;
int offst;
if ((cfPtr = fopen("studenti.dat", "r+")) == NULL) printf("Non possibile aprire il file !!!.\n");
else
/* Scrive record in un file random già inizializzato con record vuoti*/
Random Access File
Programma esempio Scrittura random di record nel file
while (studenteSannio.matricola != 0) { printf(“Cognome:\n ");
fflush(stdin);
gets(studenteSannio.cognome);
printf(“Nome:\n ");
fflush(stdin);
gets(studenteSannio.nome);
printf(“Media Voti:\n ");
fflush(stdin);
scanf(“%f“, &studenteSannio.media_voti);
offst = (studenteSannio.matricola - 1) * (sizeof(struct studente));
fseek(cfPtr, offst, SEEK_SET); //si posiziona per la scrittura fwrite(&studenteSannio, sizeof(struct studente), 1, cfPtr);
printf("Immetti la matricola (da 1 a 100, 0 per terminare)\n");
scanf("%d", & studenteSannio.matricola);
} }
fclose(cfPtr);
printf("FINE PROGRAMMA\n");
}
/* Legge e stampa record ‘pieni’ da un file random */
#include <stdio.h>
main()
{ struct studente{
int matricola;
char cognome[15];
char nome[10];
float media_voti;
};
FILE *cfPtr;
struct studente studenteSannio;
cfPtr = fopen("studenti.dat", "r") if (cfPtr == NULL)
printf(“Apertura file non possibile !!!\n");
else
{printf("%6s - %16s - %11s – %10s\n", “Matr.", “Cognome“, “Nome", “Media");
while (!feof(cfPtr))
{fread(&studenteSannio, sizeof(struct studente), 1, cfPtr);
if (!feof(cfPtr))
if (studenteSannio.media_voti != 0)
printf("%6d - %16s - %11s - %10.2f\n", studenteSannio.matricola,
studenteSannio.cognome, studenteSannio.nome,studenteSannio.media_voti);
} }
fclose(cfPtr);
Random Access File
Programma esempio Lettura dei record nel file
13
Definizione del problema:
Si vogliono memorizzare su un file ad accesso random il numero di matricola, il cognome, il nome, l’indirizzo di e-mail ed il numero di telefono degli studenti del corso di elementi di informatica; si vogliono poi visualizzare tutte leinformazioni registrate ed eventualmente aggiungerne altre o ricercare, aggiornare o cancellare un elemento in base al numero di matricola o all’indirizzo di e-mail.
Definizione della specifica del programma:
LO STUDENTE COMPLETI E SCRIVA IL PROGRAMMA (STRUTTURATO CON SOTTOPROGRAMMI) CON LA RELATIVA DOCUMENTAZIONE