File Struttura L informazione memorizzata in RAM non soddisfa alcuni requisiti: volume elevato (eventualmente > VM) persistenza / stabilità (rispetto a processi / crash / power out) condivisione / accesso simultaneo OS (file system): fornisce un astrazione della memoria di massa, vista come collezione di oggetti detti file, associati a informazione con le suddette proprietà. L oggetto file è definito/caratterizzato da aspetti quali: interazioni (Read/Write) con le applicazioni stato: include soprattutto l informazione memorizzata dipende dalla storia, influenza il comportamento futuro naming: come lo si chiama/distingue struttura: di quali elementi è fatto tipo: restrizione sull informazione o sull uso che se ne fa accesso (agli elementi del file) avviene con un interazione R/W; caratterizzato da: quali elementi sono accessibili in un dato stato come si specificano (es. posizione relativa/assoluta, chiave...) interfaccia e gestione: modalità di interazione applicazioni file protezione: di chi sono e chi può farci cosa implementazione: via interazione con I/O a. sequenza di byte (a livello di FS, non disk I/O) b. sequenza di elementi detti record (a livello di FS, non disk I/O) ispirato a schede / stampanti c. record (anche variabili), accesso a chiave (via FS, non libreria); implementazione: organizzazione ad albero ordinato su chiave Scelta attuale tipica: 1. FS del tipo (a) (DOS, UNIX) 2. oggetti-file del tipo (c) implementati su (1): attraverso librerie/api, oppure attraverso layer interno DBMS Gestione memoria - 19/01/2003 1/11 Gestione memoria - 19/01/2003 2/11
identificatori Naming naming case sensitive: pippo PippO case retentive (il nome è PippO) ma non case sensitive pippo=pippo estensione (identicatore a due componenti): prevista da FS (DOS) / convenzione d uso (Unix) solo mnemonica / riflette tipo directory Tipo di un file file speciali a caratteri / blocchi file normali, tra cui file: ASCII, organizzati in righe visualizzabili, editabili, collegabili via filtri binari: organizzazioni varie, byte non (ASCII) visualizzabili, es.: Gestione memoria - 19/01/2003 3/11 Gestione memoria - 19/01/2003 4/11
Tipo e semantica dei file OS/applicazioni riconoscono tipo da magic number o extension e ne supportano la semantica: + protezione: restrizione su operazioni incompatibili col tipo + aiuto all utente; es. (TOPS) riferimento a exe make automatico - rigidità, p.es.:.pas [pretty-printer].dat, ma.dat non si può compilare o copiare su.pas Accesso L accesso (agli elementi del file) avviene con un interazione R/W; è caratterizzato da due aspetti: quali elementi sono accessibili in un dato stato del file come si specificano P. es. per file sia di byte che di record: accesso sequenziale (il più antico, bastava per nastri) accesso casuale (per accedere a singoli record di file su disco) accesso casuale a chiave (OS DB-oriented) Tipica interfaccia: read con parametro n. record/byte o seek Su alcuni OS, l accesso deve corrispondere al tipo. Device independence a livello di interfaccia d utente e di API: accesso indipendente da collocazione fisica del file. DOS: limitata (device logica fa parte del pathname) UNIX: completa (mounting di file system sotto un altro) Esempio: l utente pippo ha due directory ciascuna su un disco piccolo: DOS: c:\pippo e d:\pippo2 UNIX: /home/pippo e /home2/pippo2 i due dischi piccoli vengono sostituiti da uno grande: DOS: c:\pippo e c:\pippo2 (device dependence) UNIX: /home/pippo e /home2/pippo2 (device independence) Gestione memoria - 19/01/2003 5/11 Gestione memoria - 19/01/2003 6/11
Attributi Operazioni / interfaccia Nome + alcuni tra: int creat(const char *path, int attrib);// file binario int open // restituisce un int detto file descriptor o handle (DOS) (const char *path,//nome del file int flags); //uno tra O_RDONLY O_WRONLY O_RDWR, in or con 0 //o più tra: O_CREAT O_EXCL O_TRUNC O_APPEND... FILE *fopen(const char *filename, //file testo/stream const char *mode); int close(int handle); int read(int handle, void *buf, unsigned len); int write(int handle, void *buf, unsigned len); long lseek(int handle, long offset, int fromwhere); // fromwhere: da inizio (0) / posizione corrente (1) / fine (2) int fstat(int handle, struct stat *statbuf); int stat(char *path, struct stat *statbuf); struct stat { short st_dev, st_ino; short st_mode, st_nlink; int st_uid, st_gid; long st_size, st_atime; long st_mtime, st_ctime; ; // p.es. struct stat s; stat( /home/pippo/f, &s); int chmod(const char *path, int amode); int rename(const char *oldname, const char *newname); int unlink(const char *filename); //cancella se ultimo link Gestione memoria - 19/01/2003 7/11 Gestione memoria - 19/01/2003 8/11
#include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #define MODE 0666 #define BUF_SIZE 4096 Esempio: cp src dst // defines O_RDONLY // exit prototype // fprintf prototype // sys calls (incl. read/write) prototypes // Unix: rw- rw- rw- Directory file system gerarchico / tree structured int main(int argc, char * argv[]) { char buf[buf_size]; int src, dst; int n_in; int code; if (argc!= 3) { fprintf(stderr, "Usage: %s src dst\n", argv[0]); exit(1); if ( (src = open(argv[1], O_RDONLY)) < 0 ) { fprintf(stderr, "Cannot open input file %s\n", argv[1]); perror("opening source file"); exit(2); if ( (dst = creat(argv[2], MODE)) < 0 ) { fprintf(stderr, "Cannot create file %s\n", argv[2]); perror("creating destination file"); exit(3); pathname assoluto / relativo current (working) directory / drive con multiprocessing, ogni processo ha una working directory una library procedure non deve cambiare w.d., o deve ripristinarla all uscita memorizzazione degli attributi in dir entry o altrove: code = 0; // arg for final exit() do { if ( (n_in = read(src, buf, BUF_SIZE)) < 0 ) { code = 4; perror("reading"); break; if (n_in == 0) // finished break; if ( write(dst, buf, n_in) < 0 ) { code = 5; perror("writing"); break; while (1); close(src); close(dst); exit(code); Gestione memoria - 19/01/2003 9/11 Gestione memoria - 19/01/2003 10/11
API / system call: Interfaccia astratta a directory system int mkdir(const char *path); int rmdir(const char *path); DIR *opendir(char *dirname); void closedir(dir *dirp); struct dirent *readdir(dir *dirp); struct dirent {// see man readdir long d_ino; // inode number off_t d_off; // offset from base of dir (as a file) to this dirent unsigned short d_reclen; // length of this d_name char d_name [NAME_MAX+1]; // file name (null-terminated) NAME_MAX=255 rewinddir(dir * dirp); // riposiziona dirp su 1 a entry in directory e assicura che // le prossime readdir ne rifletteranno l'attuale contenuto int rename(const char *oldname, const char *newname); int link(const char *filename, const char *newfilename); int unlink(const char *filename); // cancella se non ci sono link (hard) Esempio: #include <dirent.h> #include <stdio.h> #include <stdlib.h> void scandir(char *dirname) { DIR *dir; struct dirent *ent; printf("first pass on '%s':\n",dirname); if ((dir = opendir(dirname)) == NULL) { perror("unable to open directory"); exit(1); while ((ent = readdir(dir))!= NULL) printf("%s\n",ent->d_name); printf("second pass on '%s':\n",dirname); rewinddir(dir); while ((ent = readdir(dir))!= NULL) printf("%s\n",ent->d_name); if (closedir(dir)!= 0) perror("unable to close directory"); exit(2); main(int argc,char *argv[]) { scandir(argv[1]); Gestione memoria - 19/01/2003 11/11