A. Veneziani Files di record

Documenti analoghi
IL CONCETTO DI FILE. È illecito operare oltre la fine del file.

Gestione di files Motivazioni

2) FILE BINARI: è una sequenza di byte avente una corrispondenza uno a uno con la sequenza ricevuta dal dispositivo esterno.

Input/output da file I/O ANSI e I/O UNIX FLUSSI E FILE FLUSSI FLUSSI di TESTO FLUSSI BINARI FILE

Gestione dei file. File di testo e binari

Laboratorio di Programmazione Gruppo III, Ml-ZZ. Alberto Finzi

Input/output in C e in C++

Esercizi su. Istruzioni di scelta multipla. Overflow

PASCAL - Record. Il linguaggio PASCAL consente l utilizzo dei RECORD

Corso di Fondamenti di Informatica Il sistema dei tipi in C++

Files in C++ Fondamenti di Informatica. R. Basili. a.a

Architettura degli elaboratori Docente:

Strutture dati e loro organizzazione. Gabriella Trucco

file fisico file logico

Variabili e Istruzioni

Fondamenti di Informatica

Strategie di programmazione

Un file è un astrazione di memorizzazione di dimensione potenzialmente illimitata (ma non infinita), ad accesso sequenziale.

ingresso/uscita da file

Il file system. Le caratteristiche di file, direttorio e partizione sono del tutto indipendenti dalla natura e dal tipo di dispositivo utilizzato.

Riprendiamo l esercizio calcolatrice

MATLAB I/O. Informatica B - A.A. 2012/2013 ACQUISIZIONE DI INPUT DA TASTIERA

Esercizi. I File ed il C

Sommario. Le strutture dati elementari per implementare sequenze: Vettori Liste

Fondamenti di Informatica

Input / Output attraverso stream. I/O in C vs. I/O in C++

FILE BINARI FILE BINARI

1) definizione di una rappresentazione 2) specificazione di un algoritmo (dipendente dalla rappresentazione) 3) traduzione in un linguaggio

Corso di Fondamenti di Informatica

Fondamenti di Informatica II 24. Gestione I/O e File in C++

Il linguaggio C. Notate che...

Fondamenti di Informatica

INTRODUZIONE ALLA PROGRAMMAZIONE AD ALTO LIVELLO IL LINGUAGGIO JAVA. Fondamenti di Informatica - D. Talia - UNICAL 1. Fondamenti di Informatica

Costanti e Variabili

Breve Manuale di Riferimento sulla Sintassi Linguaggi C++ e FORTRAN

Indice. Ordine di valutazione. Espressioni in C++ Le espressioni in C++ (CAP 4) Alberto Garfagnini e Marco Mazzocco A.A. 2014/ * 20 / 2

Il file È un insieme di informazioni: programmi. Il File System. Il file system

INDICI PER FILE. Accesso secondario. Strutture ausiliarie di accesso

Non ci sono vincoli sul tipo degli elementi di un vettore Possiamo dunque avere anche vettori di

Processore Danilo Dessì. Architettura degli Elaboratori.

Tipi di dato strutturati: Array

Utilizza i tipi di dati comuni a tutto il framework.net Accesso nativo ai tipi.net (C# è nato con.net) Concetti fondamentali:

Laboratorio di Informatica

Informatica 1. Prova di recupero 15 Febbraio 2005

Sistemi Operativi Teledidattico

Scrittura formattata - printf

PROGRAMMA PREVENTIVO. Criteri di programmazione didattica. La programmazione didattica verrà sviluppata tenendo conto dei seguenti punti:

Definizione di file. Directory e file File binari e file di testo

FILE BINARI FILE BINARI FILE BINARI. OUTPUT BINARIO: fwrite()

Corso di Fondamenti di Informatica Classi di istruzioni 2

Elaborazione dell informazione

ISTITUTO TECNICO INDUSTRIALE STATALE LA GESTIONE DEI FILE DI TESTO IN C++

! I file di testo non sono indispensabili: sono semplicemente comodi 1. Sintassi:

Elementi di C++ di base

Uno stream rappresenta un flusso di dati da cui e' possibile

Appunti del corso di Informatica 1 (IN110 Fondamenti) 5 Rappresentazione delle informazioni

Algebra di Boole: Concetti di base. E un algebra basata su tre operazioni logiche

Parametri Formali di una Funzione e Record di Attivazione

Tipi di dati strutturati e Linguaggio C. Record o strutture Il costruttore struct in C

Word 2003 Lavorare col testo

Tipi di dati scalari (casting e puntatori) Alessandra Giordani Lunedì 10 maggio 2010

Text files, streams. I file che ci interessano sono file di testo. anche se, logicamente, contengono numeri o altro

Caratteristiche di un linguaggio ad alto livello

Unità Didattica 5 Linguaggio C. Stringhe. Accesso a file ASCII. Strutture.

Tipi di dato. Unità 2. Domenico Daniele Bloisi. Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER

Definizione di metodi in Java

Array. Maurizio Palesi Salvatore Serrano. In C si possono definire tipi strutturati Vi sono due costruttori fondamentali

Corso di Fondamenti di Informatica. Puntatori e Allocazione Dinamica

Via Onedo 1/A Abbadia Lariana 1/A - Tel: , P.I.: Web:

FILE BINARI FILE BINARI

Espressioni logiche. Espressioni logiche. Operatori logici. Operatori logici. Operatori logici. Espressioni Logiche e Istruzione di Test

Strutture Dinamiche. Fondamenti di Informatica

Tipi di dato. Le variabili in C. Problema: dato in input un carattere, se esso è una lettera minuscola, trasformarla in maiuscola.

BOZZA. cin per la comunicazione dal dispositivo di input standard, la tastiera, al programma (stream di input standard)

Informatica 1. Prova di recupero 21 Settembre 2001

C3 IL DBMS MICROSOFT ACCESS

Il file system. Il File System. Attributi del file. File

Suggerimenti, note utili ed errori comuni. Fondamenti di informatica T

Informatica 1 Tipi e dichiarazioni in C++ C++ - Tipi e dichiarazioni 1

A. Veneziani - Classi IV A e IV B - Classe stack dotata di interfaccia grafica

L Allocazione Dinamica della Memoria

Università degli Studi di Cassino Corso di Fondamenti di Informatica Tipi strutturati: Stringhe. Anno Accademico 2010/2011 Francesco Tortorella

Corso di Fondamenti di Informatica

Puntatori in C. Puntatori. Variabili tradizionali Esempio: int a = 5; Proprietà della variabile a: nome: a

Elementi lessicali. Lezione 4. La parole chiave. Elementi lessicali. Elementi lessicali e espressioni logiche. Linguaggi di Programmazione I

Lettura e scrittura di file di dati input/output

I file Laboratorio di Linguaggi di Programmazione a.a. 2001/2002

Laboratorio di Algoritmi e Strutture Dati

Prova di Laboratorio del [ Corso A-B di Programmazione (A.A. 2004/05) Esempio: Media Modalità di consegna:

Aritmetica dei Calcolatori 3

Modulo 1 Concetti di base della Tecnologia dell Informazione

Corso di Fondamenti di Informatica (M-Z)

Argomenti della lezione. Introduzione agli Algoritmi e alle Strutture Dati. Lista Lineare. Lista Lineare come Tipo di Dato Astratto

Università di Roma Tor Vergata L12-1

Capitolo 11 Elaborazione di file

Laboratorio Progettazione Web Il linguaggio PHP Le Istruzioni. Andrea Marchetti IIT-CNR AA 2014/2015

Lezione 8 Struct e qsort

Dati aggregati. Violetta Lonati

MODELLI DEI DATI. Informatica Generale (AA 07/08) Corso di laurea in Scienze della Comunicazione Facoltà di Lettere e Filosofia

Note sull utilizzazione di componenti logici di tipo memoria

Transcript:

A. Veneziani Files di record Caratteristiche dei file di record I file di record si differenziano rispetto a quelli di testo per avere i dati memorizzati in un formato predefinito ben preciso suddiviso in campi di varia lunghezza, ognuno contenente dati dello stesso tipo. Essi sono da considerarsi una specifica categoria di file binari (si ricorda che file di tipo binario sono anche, ad esempio, le immagini e i file eseguibili (.exe)). La definizione del formato interno di un file di record è data dalla struttura utlizzata per definire il record stesso. Infatti, mentre nelle operazioni di lettura / scrittura su files di testo operiamo con variabili, a seconda dei casi, di tipo char, vettore di char o string, ossia variabili appunto, per loro natura, atte a contenere testo o caratteri, sui file di record operiamo con variabili in vario modo strutturate 1. Tali variabili dovranno avere la precipua caratteristica di avere una ampiezza ben definita e quindi costante. In un file di record infatti la scrittura di un record comporta l aumento della dimensione del file di una ben precisa quantità di bytes. Uno schema che rappresenti la memorizzazione in un file di record può essere disegnato come: Alunno Voto Materia Rossi 6 Inglese Bianchi 5 Matematica... L esempio descrive un file di record dove il record è costituito, nel nostro caso, da tre campi: Alunno alfanumerico Voto numerico Materia alfanurico Per tali campi si dovrà definire una ampiezza ben definita, o uno specifico tipo con apiezza definita. Il fatto che il record sia un modulo le cui dimensioni hanno ampiezza fissa e nota semplifica molte operazioni rispetto ai file di testo. Ad esempio è semplice nei file di record effettuare la modifica dei contenuti di un record e la cancellazione di un record (con un eventuale successivo recupero di spazio). Il record di cui sopra potrebbe essere definito con la struttura C++: struct prova char alunno[30]; int voto; char materia[50]; ; Esso ha una ben precisa ampiezza per tutti i campi (30 byte per nome, 4 byte per il voto, 50 byte per la materia), la cui somma definirà l ampiezza di tutto il record 2, numero che comunque sarà sempre fisso per tutti i record. Apertura di un file di record L apertura di un file di record avverrà con il solito metodo open( ), usato in modo analogo ai file di testo, ma in modalità binaria. L oggetto a cui sarà applicato il metodo open sarà come al solito un oggetto della classe fstream, come per i file di testo. Nel campo modalità sarà presente quindi la specifica ios::binary, che indica tale modalità. Un tipo di estensione che può essere propriamente usata per tali file è.dat. 1 Di tipi definiti tramite l istruzione struct 2 a meno di byte di allineamento, spesso presenti per scopi interni al sistema, che possono far aumentare il numero di byte di qualche unità Pagina 1

Quindi alcune modalità comuni di apertura per i file di record sono: ios::in ios::binary Sola lettura ios::out ios::binary Sola scrittura + creazione ios::out ios::app ios::binary ios::in ios::out ios::trunc ios::binary Modalità di aggiunta in coda + creazione Lettura + scrittura + creazione Lettura e scrittura di record Quando si opera su files di record per legere e scrivere dovranno essere utilizzati due nuovi metodi specifici per essi. Il metodo read ha due parametri ed è conformato come: <oggetto fstream>.read((char*) &<var. strutturata>, <dimensione del record>); L indicazione (char*) ha lo scopo di effettuare un cast di puntatori, tale per cui il puntatore alla variabile strutturata, viene convertito in un puntatore a carattere (o meglio indicante il punto di inizio di una serie di caratteri). Il primo parametro quindi fornisce l indirizzo di inizio della struttura in memoria. Il secondo la sua ampiezza, permettendo quindi di avere dati utili per svolgere l operazione di lettura. Analoga sintassi si ha per la scrittura di un record, solo che qui si utilizzerà il metodo write: <oggetto fstream>.write((char*) &<var. strutturata>, <dimensione del record>); Si noti che la sintassi è analoga anche perchè i dati passano dal programma al file tramite parametri by reference (puntatori), quindi è un passaggio atto ad operare sia dal programma verso il metodo e quindi il file, sia dal metodo verso il programma. Esempi concreti di sintassi potrebbero essere: struct rec char nome[50]; int n; ;... int main() fstream fs; rec r; fs.write((char*) &r, sizeof(rec)); Funzione sizeof( ) Come mostrato negli esempi qui sopra il problema di individuare l ampiezza di una struttura può essere risolto tramite l uso della funzione sizeof(.), che attende come parametro il nome di una variabile (semplice o strutturata) o alternativamente un tipo di dato e come uscita rende la sua ampiezza come numero di byte. Ciò permette ai metodi read e write di conoscere quanti byte vadano letti o scritti. Pagina 2

Metodo eof() Anche nei file di record non è noto a priori quale sia il numero di record che andranno letti dal file. Data questa situazione, analogamente a quanto fatto nei file di testo, si controlla ad ogni lettura se i record siano stati letti tutti. In tal caso eof( ) sarà true. La lettura avviene, come al solito, tramite un ciclo. Un esempio di un tale ciclo di lettura di records potrà essere: while (! fs.eof()) if (! fs.eof()) cout << r.nome << " " << r.n << endl; ove il record letto viene trasferito, con una sola operazione, nella var. strutturata r, per poi essere utilizzato. Riposizionamento del punto di lettura - metodo seekg( ) Dopo la scrittura di un certo numero di records se il programma và a rileggere il file si scoprirà che esso non vede i suoi contenuti. Ciò è dovuto al fatto che anche il punto di lettura è in fondo al file. In tal caso bisogna operare per riportarlo in cima ad esso. Ciò può essere fatto con: fs.seekg(0); o in alternativa: fs.seek(0, ios::beg); Una volta effettuata questa operazione tutti i record saranno leggibili operando con altre opportune operazioni. In pratica il punto di lettura viene spostato all inizio del primo record, ossia all inizio del file di record. Lunghezza di un file Per conoscere la lunghezza di un file sia di testo che di record basterà ricorrere a questo codice: fs.seekg(0, ios::end); ampiezza = fs.tellg(); il valore ampiezza (int) renderà l ampiezza del file in di byte. Infatti: fs.seekg(0, ios::end); indica al cursore di spostarsi con il cursore alla fine del file (scostamento 0 byte, dalla fine del file - ios::end 3 ). L istruzione ampiezza = fs.tellg(); serve a indicare di quanti byte sia ora scostato il punto di lettura dall inizio del file. Le due operazioni combinate danno l ampiezza. Metodo clear() In alcuni casi (tipicamente dopo aver raggiunto uno stato di eof), l oggetto fstream (fs) deve essere resettato ad uno stato non di errore, per poter operare di nuovo. Questo viene fatto quando necessario tramite il metodo clear: fs.clear(); 3 Si noti l uso negli ultimi esempi delle due costanti ios::beg e ios::end, rappresentanti l inizio e la fine del file. Pagina 3

Posizionamento sul record n Potendo operare in modo modulare su un qualunque record è ovviamente importante essere capaci di posizionarsi correttamente sul record voluto. Ciò viene fatto tramite l istruzione: fs.seekg((n 1) * sizeof(rec)); questa istruzione permette di raggiungere direttamente il record n 4, evitando la lettura dei precedenti. Infatti se si pensa di saltare al primo record, si avrà che dato che (n 1) = (1 1) da 0, non si avrà spostamento da effettuare. Ciò è corretto essendo l inizio del record 1 all inizio del file. Per i record successivi il numero di spostamenti pari all ampiezza del record (valore ricavato tramite sizeof(rec) ), sarà anche in questo caso corretto. Ad esempio per raggiungere il record 3, dovrò spostarmi all inizio del record 3, quindi saltare due record, cosa che infatti viene indicata dalla istruzione precedente: (n 1) = (3 1) = 2 * sizeof(rec), ossia una spostamento pari all ampiezza di due record. Modifica di un record Come si è già detto precedentemente l operazione di modifica di un record è una operazione piuttosto comune e comporta: a) il posizionamento sul record da modificare b) la successiva lettura del contenuto c) la modifica dei valori d) un riposizionamento sul record n e) ed infine una scrittura dello stesso record, con sua sovrascrittura su disco in codice C++ le precedenti operazioni divengono: fs.seekg((n - 1) * sizeof(rec)); // posizionamento // lettura valori r.n = r.n * 3; // modifica - (si supponga che la modifica sia triplicare il valore numerico) fs.seekg((n - 1) * sizeof(rec)); // ri-posizionamento fs.write((char*) &r, sizeof(rec)); // scrittura valori modificati Il motivo del secondo posizionamento (indicato come ri-posizionamento) è che il cursore come al solito dopo una lettura avanza della quantità di byte letti (in questo caso di un intero record). Proprio per questo per posizionarsi di nuovo sul record voluto e non scrivere le modifiche sul successivo bisogna effettuare un ri-posizionamento che viene compiuto semplicemente eseguendo di nuovo una istruzione di posizionamento identica alla precedente. Cancellazione di un record Nel caso si vada a cancellare un record di solito si ricorre alla cancellazione logica. La cancellazione fisica del record infatti presuporrebbe il ricompattamento di tutti i record, ossia la riscrittura di parte del file, operazione assai onerosa. Per permettere la cancellazione logica, bisogna prevedere all interno del record un apposito campo che indichi o no se il record sia valido (ossia se i suoi dati siano o no cancellati). Talo valore sarà quindi di solito un campo booleano apposito (di solito inserito nell ultima posizione della struttura). Nel record da noi preso come esempio operativo a pagina 1, dovremo quindi mdoficare il record come: struct rec char nome[50]; int n; 4 I record di norma sono numerati partendo dal numero 1. Pagina 4

bool cancellato; ; In tal caso: una operazione di scrittura verrà sempre effettuata con il valore booleano a false, mentre una operazione di cancellazione su un certo record porterà tale campo a true, ossia ad assumere un valore che indichi il fatto che il record non è più valido. In questo modo le successive operazioni se contenenti opportuno codice potranno evitare di considerare i record che risultano come cancellati, controllando il valore del campo apposito. C è anche da notare che successive operazioni di inserimento dovrebbero recuperare lo spazio relativo a records liberi e non andare ad impegnare ulteriore spazio disco inutilmente. Viceversa il file di record alla lunga aumenterebbe la sua dimensione continuamente. Un frammento di codice che effettui la cancellazione selettiva e di conseguenza non ristampi il record cancellato, è riportato qui sotto: cout << "Fornisci il record da cancellare: "; cin >> n; fs.seekg((n - 1) * sizeof(rec)); r.cancellato = true; fs.seekg((n - 1) * sizeof(rec)); fs.write((char*) &r, sizeof(rec)); fs.clear(); fs.seekg(0); while (! fs.eof()) if (! fs.eof()) if (! r.cancellato) cout << r.nome << " " << r.n << endl; Pagina 5