Domenica Pomeriggio... - by Dreadnaut (c) 2002

-- Tutto quello che mi e' venuto in mente sui files, una domenica pomeriggio che non sono uscito con la mia ragazza -- ver 0.2 ( scusa ufficiale: era brutto tempo / scusa reale: al momento non ne ho una ) Tutti i file su disco, di qualunque tipo, sono solamente una sequenza finita e non strutturata di byte. A questo livello non c'e' nessuna distinzione fra file di testo, di dati, fra l'immagine di sfondo del desktop e le 300 pallosissime pagine di dispense che vi dovete studiare... Cioe' che rende differenti i files e' il modo di interpretarli, ovvero come vengono lette le informazioni e come vengono caricate in memoria. Il pascal offre una prima distizione fra due modi di accesso ai file: - file di testo - var t: text; - file binari - var f: file [of <tipo>]; Questo documento si occupa solo del secondo tipo: file binari tipati e non. Il tipo file in pascal e' un tipo complesso, che corrisponde poi ad un record di informazioni, di solito invisibili, utilizzate dalla unit system per accedere al file. La struttura e' cosi' definita: type { Typed and untyped files } TFileRec = record Handle : word; Mode : word; RecSize : word; Private : array[1..26] of byte; UserData: array[1..16] of byte; Name : array[0..79] of char; end; Se volete accedere ai campi dovete utilizzare un casting sulla variabile file: [ var f: file; ] with TFileRec(f) do <etc etc> ma questo, sebbene spunto di interessanti paranoie, poco importa. La struttura e' un po' diversa per i file `text' e si possono fare cose molto piu' divertenti... ma questa e' un'altra storia... Una variabile dichiarata semplicemente file e' un file non tipato, cioe' costituito da record di lunghezza fissata ma senza una particolare struttura (aka tipo) interna. La dimensione del record e' specificata al momento della apertura del file che avviene utilizzando la procedura reset: reset ( f, [<rec_size>] ); se il parametro viene omesso la dimensione di default e' 128 bytes. Lettura e scrittura su file non tipati sono permesse soltanto attraverso le procedure blockread e blockwrite: blockread ( <file>, <buffer>, <num_blocchi>, [<risultato>] ); La procedura si occupera' di caricare dal file <num_blocchi> della dimensione sopra definita e infilarli in <buffer> (una qualsiasi variabile, dinamica o statica e' lo stesso basta che sia grande a sufficienza: il massimo che potete caricare e' cmq limitato ai soliti ~ 64 kB). Se aggiungete la variabile risultato (:word) questa conterra' il numero di blocchi effettivamente caricati dal file (utile da confrontare con il valore di <num_blocchi>, cioe' il numero di blocchi che _vorreste_ fossero stati caricati da disco) I files non tipati sono molto comodi per aprire file di formati generici, cioe' costituiti da parti eterogenee ma comunque separabili in `blocchi': fissando la dimensione del record ad 1 byte, possiamo caricare qualsiasi struttura dal file con blockread (f, varA, sizeof(varA) ); e siamo legati solo al byte, cioe' alla struttura minima di cui puo' essere costituito un file. Definire un file come file of byte/char potrebbe sembrare equivalente, ma blockread/write accettano solo file untyped ! Definendo invece variabili come file of <tipo> fissiamo a struttura interna del file ad una serie di record tutti dello stesso <tipo>: possiamo leggere e scrivere ovunque nel file ma sempre blocchi strutturati allineati con la dimensione del record (ci aiuta la funzione seek, permettendoci di saltare all' n-esimo blocco [vale anche per i file untyped]). Ottimo per un file costituito da campi identici, un database, un agenda, ma di certo poco flessibile: non potra' ad esempio esistere nel file un header, a meno di non `schiacciarlo' nel <tipo> che regna incontrastato sul file. Su files tipati e' possibile operare con le normali read e write (ricordandosi di specificare come primo parametro il file) ma cmq per leggere un solo record alla volta. Niente letture violente di intere array, ne bufferizzazioni: un record per volta come se leggessimo un carattere da tastiera. La principale differenza implementativa nell'accesso fra file tipati e non tipati e' semplicemente sulle restrinzioni sulle procedure utilizzabili: - i file tipati possono solo leggere record uno per volta (read) - i file untyped possono leggere solo blocchi di record (da 1 a 2^16) (blockread) Ad entrambi si accede in modalita' promisqua: la lettura e' sequenziale ma e' possibile saltare da una posizione all'altra tramite seek ed ottenere l'accesso random [ chi si ricorda GET file,#n,... in basic ? com'era ? :-) ] Entrambi sono suddivisi in blocchi di identica dimensione: - i typed fissano anche la struttura di questi blocchi, ma fra casting, puntatori e absolute chi ci fa' caso ? :-) - gli untyped permettono di lavorare su multipli del tipo base, e quindi su strutture complesse e variabili a run-time; risultano percio' piu' versatili se applicati a tipi di file complessi: ovunque ci sia la necessita' di leggere un header, valutarne il contenuto, leggere blocchi di diverse dimensioni in base all'header (cioe' il 90% dei formati di file comunemente usati) l'uso di variabili file tipate beh... e' un po' masochista ;-) Nella gestione di strutture fissate e dimensionalmente invariabili e' invece molto comodo non doversi preoccupare dell'implementazione del <tipo> e percio' la versione typed si rivela molto piu' comoda: non e' piu' necessario conoscere il record che ci apprestiamo a leggere/scrivere ma lo consideriamo semplicemente come una scatola chiusa, tranquilli che nel file sara' circondato solo da suoi simili; potremmo comportarci in modo omogeneo e questo si tradurra' in meno sbattimento. { -------------------------------------------------------------------------- } Topic nell'help del TP7 - file (reserved word) e file-record - la struttura TFileRec, - Read/Write e BlockRead/BlockWrite - System-Procedures-(categorical) tutte le I/O procedures and functions { -------------------------------------------------------------------------- } -eof- 05/05/02 - (c) 2002, Dreadnaut production Il contenuto di questo documento e' da considerarsi esclusivamente invenzione dell' autore, ogni riferimento a cose o persone realmente esistenti e' puramente casuale e non voluto.