IFT-10541 Structures de données Abder Alikacem Département d’informatique et de génie logiciel
Les fichiers binaires • Principe - un fichier est une séquence d'octets non interprétés • Interprétation des données binaires - à la charge du programmeur - une séquence de n octets peut s'interpréter comme: un entier, un tableau, un enregistrement, ... Les outils Déclaration d’un pointeur de fichier Ouverture et fermeture Les différents modes d’ouverture Lecture et écriture Principe du numéro d’ordre relatif (rrn) Accès direct..
Accès direct avec fseek() typedef struct { int age; char nom[10]; } Personne; Personne p; FILE*f; … • Ecriture dans le fichier f=fopen(nomFich, "w+b") fwrite (&p, sizeof(Personne), 1, f); • Lecture du fichier fread (&p, sizeof(Personne), 1, f); Accès direct pour lire ou écrire: fseek (f, rrn*sizeof(Personne), SEEK_SET) déplacement par rapport à origine SEEK_SET début de f SEEK_CUR position courante SEEK_END fin de f
Positionnement dans un fichier La fonction int rewind(FILE *flot); permet de se positionner au début du fichier. Elle est équivalente à fseek(flot, 0, SEEK_SET); long ftell(FILE *flot); retourne la position courante dans le fichier (en nombre d'octets depuis l'origine). Suggestion de lecture avec des exemples: http://w3.ift.ulaval.ca/~abali/ift-17582/Semaine13/ManipulationFichiersBinaires.html
Organisations et modes d’accès des fichiers Mode d’organisation Séquentiel Relatif ou direct Séquentiel indexé Mode d’accès séquentiel Mode d’accès direct Hashing Mode d’accès indexé
Structure typique d’un arbre-B typedef struct { short keycount; /* Le compteur de clefs. Indique quand le noeud est plein. */ struct uneCle key [MAXKEYS]; /* Le tableau des clef. */ short CHILD[MAXKEYS+1]; /* Le tableau qui contiendra les fils pointés */ } BTPAGE;
/* ouverture du fichier index*/ if btOpen() root = getRoot(); Ajout dans un arbre-B int main() { …… /* ouverture du fichier index*/ if btOpen() root = getRoot(); else { btfd = fopen("btree.dat", "wb+"); key = getClef(); /*première clé*/ root = createRoot(key, NIL, NIL); } key = getClef(); /* une clé à insérer*/ do { promoted = insert(root, key, &promoRrn, &promoKey); if (promoted) root = createRoot(promoKey, root, promoRrn); key = getClef(); } while( /* il y a une clé*/ );
Ajout dans un arbre-B /* **** insert.c **** Contient la fonction insert() qui insère une clef dans un arbre-B. S'appelle de manière récursive tant que le bas de l'arbre n'est pas atteint. Alors, insert() insère une clef dans une feuille de l ’arbre. Si le noeud est plein, - appelle split() pour scinder le noeud - promotion de la clef du milieu et le rrn du nouveau nœud et essaie d’insérer la clé promue lors de ses remontées d’appel */ /* insert() Arguments: rrn: Le rrn de la page dans laquelle on fait l'insertion *promoRchild: Le fils promu vers le prochain niveau key: La clef à être insérée *promoKey: La clef promue vers le prochain niveau
insert (short rrn, clef key, short *promoRchild, clef *promoKey) { …. if (rrn == NIL) { *promoKey = key; *promoRchild = NIL; return (VRAI); } btread(rrn, &page); found = searchNode(key, page, &pos); if (found) { printf("Erreur: clé dupliquée); return (FAUX); promoted = insert(page.child[pos], key, &pBrrn, &pBkey); if (!promoted) return (FAUX); if (page.keycount < MAXKEYS) { insInPage(pBkey, pBrrn, &page); btWrite(rrn, page); else { split(pBkey, pBrrn, &page, promoKey, promoRchild, &newPage); btwrite(rrn, page); btwrite(*promoRchild, newPage);
Recherche dans un arbre-B RECHERCHE (RRN, CL, TROUV_RRN, TROUV_POS) si RRN == NIL alors /* condition d'arrêt de la récursion */ retourner NON TROUVE sinon lire page RRN dans PAGE regarder à travers la PAGE pour trouver CL mettre POS égale à la position où KEY apparaît ou devrait apparaître. si CL est trouvé alors /* RRN contient la clef */ TROUV_RRN = RRN TROUV_POS = POS retourner TROUVE sinon /* le FILS suivant fait référence à un niveau plus bas*/ return (RECHERCHE(PAGE.FILS[POS], CL, TROUV_RRN, TROUV_POS) finsi
Bool searchBTree(int rrn, uneCle key, int *trouvRRN, short *trouvPos) { short pos; Bool found; BTPAGE page; if (rrn == NIL) return FAUX; } else btread(rrn,&page); /*lecture d'un noeud (une page) dans le fichier B-Arbre*/ found = searchNode(key, page, &pos); /*recherche dans la page lue */ if (found) *trouvRRN = page.key[pos].RRN_FichPrin; return true; return(searchBTree(page.child[pos],key,trouvRRN,trouvPos)); /* RRN_FichPrin est le numéro du bloc dans le fichier de données (FichPrin) où se trouve toutes les données de l'enregistrement trouvé. Chaque clé est accompagnée par l'adresse où se trouve la donnée correspondante dans un autre fichier que le fichier index B-Arbre.*/
Visite d’un arbre-B visite symetrique du B-arbre pour afficher les clés triées rrn est l'adresse de la page racine du B-arbre cette fonction retourne un flag pour contrôler son exécution BTPAGE est la structure typique du B-arbre: typedef struct { short keycount; struct uneCle key [MAXKEYS]; short CHILD[MAXKEYS+1]; } BTPAGE;
int visiteSymetriqueB_Arbre(short rrn) { BTPAGE page; short pos; if (rrn == NIL) return (-1); //arbre vide } btRead(rrn, &page); for(pos = 0; pos < page.keycount; pos++) /*appel recursif pour chaque sous-arbres*/ visiteSymetriqueB_Arbre(page.child[pos]); printf(" - %s ", page.key[pos].nom); /*dernier appel récursif pour le sous-arbrequi se trouve à droite de la dernière cle*/ return 0;