Gestion de Fichiers Concepts Fondamentaux et Fichiers dEnregistrements
2 Plan du cours daujourdhui Concepts fondamentaux Champ et organisation des enregistrements Gestion des fichiers denregistrements Accès aux enregistrements Accès direct versus accès séquentiel Points selectionés de FZR ;
3 Champ et enregistrements Jusquà présent nous avons conçu les fichiers comme un train discontinu de données. Maintenant nous allons étudier les fichiers comme une collection denregistrements (records) composés de champs (fields). Le champ est lunité de base des données. Un champ contient une valeur de donnée unique. Plusieurs champs sont organisés en enregistrements.
4 Champ et enregistrements (suite) Considérons le programme ci-bas (Détails dans FZR) #include main() { Person p; fstream infile; Outfile.open(personnes.txt",ios:out); while (1) { cin >> p; //Lire les champs de la personne if (strlen(p.LastName)==0) break; Outfile << p; //Ecrire les champs de la personne } Outfile.close(); }
5 Champ et enregistrements (suite) Considérons le fichier dentrée suivant pour le programme Iluju Kiringa Joe Alisson 180 Lees 800 King Ottawa Toronto On On K1S5J6 M4Y1R6 Le fichier de sortie de notre programme contiendra Iluju Kiringa180 LeesOttawaOnK1S5J6JoeAlisson800 KingTorontoOnM4Y1R6 Ainsi nous avons obtenu un train continu doctets quil est difficile de comprendre ! Pour comprende linfo initiale, nous avons besoin dorganiser notre train doctets en enregistrements.
6 Champ et enregistrements (suite) Dans notre exemple, notre fichier de sortie contient des infos sur des personnes. Et nous avons donc besoin dune organisation de fichier qui nous rappèle la signification originale de nos octets, à savoir des infos sur des personnes. De là limportance des champs constituant une personne. Un champs est de ce point de vue la plus petite unité significative dinformation dans un fichier.
7 Structure des champs (Fig. 4.3 dans FZR) Fixer la longueur des champs: Champs à longueur fixe Enregistrement à longueur fixe Accès facile aux données (simple arithmétique) Désavantage: perte despace en fin de champs Débuter chaque champ par un indicateur de longeur: Utiliser comme indicateur de longeur pour des champs courts (<=256 octets) Désavantage: larithmétique des adresse devient difficile pour ds champs longs (>=256 octets)
8 Structure des champs Séparer les champs par des délimiteurs: Le délimiteur doit être judicieusement choisi Le délimiteur est placé à la fin de chaque champ Désavantage: possible confusion du délimiteur avec un octet significatif Utiliser des expression Clé=Valeur pour identifier chaque champ: Prénom=iluju|nom=kiringa| ….|code=K1S5J6 Ce type dorganisation est appelé auto-descriptif Désavantage: beaucoup despace est allouée aux clés
9 Structure des enregistrements (Fig. 4.5) Organiser les données en champs ne suffit pas encore. Pourquoi? Une organisation du fichier en enregistrements savère nécessaire. Plusieurs methodes existent pour regrouper les champs en enregistrements. Elles sont similaires aux méthodes dorganisation des champs déjà vues. Les enregistrements sont stockés dans les fichiers, mais sont appelés objets lorsquils résident en mémoire principale. En C++, nous utiliserons une déclaration de classe pour décrire les objets en mémoire principale.
10 Structure des enregistrements (suite) Enregisrements à longueur fixe: Cependant, fixer la longueur dun enregistrements nentraîne pas un nombre fixe de champs ! En fixant la longueur des champs, on fixe aussi celle des enregistrements On peut avoir un enreg. à longueur fixe avec des champs de longueur variable ou un # de champs variable. Enregistrements à nombre de champs fixe: On peut fixer le # de champs quun enreg. peut contenir. Reconnaître un enreg. se fera simplement en comptant le # de champs lus: il faut donc compter modulo ce nombre.
11 Structure des enregistrements (suite) Enregistrement à indicateur de longueur: Débuter chaque enreg. par un indicateur de longueur. Très utile pour des enreg.s à longueur variable. Enregistrement à index dadresses: Utiliser un fichier index pour stocker les adresses des enreg.s du fichier de données. Les adresses stockés sont en fait des décalages de chaque enreg. par rapport au début du fichier. Enregistrements à délimiteur: Placer un délimiteur à la fin de chaque enreg. Souvent lextrémité d'une ligne (« end-of-line ») est utilisé; en UNIX cest «\n».
12 Structure des enregistrements (suite) Aucune des méthode dorganisation des enreg.s nest idéale pour tous les contextes. Tout dépend de la nature des donnés à stocker. Enreg. avec indicateur de longueur et délimiteur de champs: Ecriture dans un fichier: int WritePerson (ostream & stream, Person &p) { char buffer[200]; …. srtcat(buffer, p.Province) ; strcat(buffer,|) ; …. short length = strlen(buffer); // Calculer la longueur de lenreg. stream.write(&length, sizeof(length)); // Ecrire la longueur au début stream.write(&buffer,length); // Ecrire lenreg. return 1; }
13 Structure des enregistrements (suite) Enreg. avec indicateur de longueur et délimiteur de champs: Lecture dun fichier: int ReadPerson (istream & stream, Person &p) { short length; stream.read(&length,sizeof(length)); //Lire la longueur de lenreg. char * buffer = new char[length+1]; // Créer un tampon stream.read(&buffer, length); // Lire lenreg. dans le tampon buffer[length] = 0; // Terminer le tampon avec la séquence null istringstream strbuff (buffer); // Créer un string stream (???) // Consulter Lipmann et Lajoie sur in-memory input-output strbuff >> p; // Utiliser lop. dextraction (saturé) return 1; }
14 Structure des enregistrements (suite) Un cliché du fichier (« file dump ») permet de voir la configuration des octets dudit fichier. Supposez que la longueur dun enreg. est 40 et que ce « 40 » est stocké comme nombre. Sa représentation dans le fichier differera selon que on le prend pour une séquence de caractères (ASCII) ou un nombre: séquence: 40Ames|Mary|123 … ASCII: \0 ( Ames | Mary | 123 … Raison: 40 décimal = 0028 hex. stocké en 2 octets = \0 ( en ASCII Les ASCII sont lisibles; les nombres, étant en binaire, ne le sont pas. Dans la pratique, vous trouverez ce mélange de types de données différents dans un même fichier.
15 Gestion des fichiers denregistrements Puisque lenregistrement est maintenant consideré comme la quantité dinformation à lire et à écrire, il est important de ne pas confondre les enregistrements. Pour ce faire, les clés primaires sont nécessaires. Une clé primaire identifie exactement un enreg. Une clé primaire ne devrait jamaiscontenir de données. Une clé secondaire identifie également un enreg., mais de manière non unique.
16 Gestion des fichiers denregistrements: accès séquentiel versus accès direct Accès séquentiel: Rechercher les enregistrements lun après lautre en séquence jusquà ce que un appariement (matching) soit trouvé. Approprié lorsque le fichier est court (peu denreg.s) Accès direct: Sauter directement à lendoit approprié dans le fichier. Cela ne prend donc comme temp que O(1) ! Cela nest possible que lorsque lon connait le numéro relatif denreg. (relative record number - RRN) de lenreg. cherché. Le premier enreg. a un RRN 0, le 2ème 1, etc.
17 Accès direct par le RRN Exigeance: enregistrements à longueur fixe Exemple: RRN = 3 -- càd le 4ème enregistrement longueur denreg. = 30 décalage (offset) = 20 x 3 = 60 Allez directement à un octet donnée en faisant de la recherche (seeking): En C++: utiliser les pointeurs seekg et seekp fichier_source.seekg(décalage,origine); fichier_source.seekp(décalage,origine); Signification: aller à loctet décalage dans le fichier fichier_source; Origine = ios::beg, ios::cur, ios::end, etc.