IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Cours complet pour apprendre à programmer en D


précédentsommairesuivant

23. Fichiers

Nous avons vu dans le chapitre précédent que les flux d'entrée et de sortie standard peuvent être redirigés vers et depuis des fichiers ou d'autres programmes avec les opérateurs >, < et | dans la console. Malgré leur puissance, ces outils ne sont pas adaptés dans toutes les situations parce que dans beaucoup de cas, les programmes ne peuvent pas effectuer leurs tâches en lisant leur entrée et en écrivant sur leur sortie.

Par exemple, un programme qui gère des enregistrements d'étudiants pourrait utiliser sa sortie standard pour afficher le menu du programme. Mais un tel programme aurait besoin d'écrire les enregistrements dans un fichier plutôt que dans stdout.

Dans ce chapitre, nous allons voir comment lire et écrire des fichiers du système de fichiers.

23-1. Concepts fondamentaux

Les fichiers sont représentés par la structure File du module std.stdio. Comme je n'ai pas encore présenté les structures, il faudra accepter leur syntaxe telle quelle.

Avant de rentrer dans le code, il faut voir les idées fondamentales à propos des fichiers.

23-1-1. Le producteur et le consommateur

Les fichiers qui sont créés sur une plateforme peuvent ne pas être utilisables tels quels sur d'autres plateformes. Simplement ouvrir un fichier et écrire des données dedans peut ne pas être suffisant pour que ces données soient disponibles au consommateur. Le producteur et le consommateur des données doivent d'abord se mettre d'accord sur le format des données qui sont dans le fichier. Par exemple, si le producteur a écrit l'identifiant et le nom des enregistrements des étudiants dans un certain ordre, le consommateur doit lire les données dans le même ordre.

De plus, les exemples de code ci-après n'écrivent pas de BOM au début du fichier. Ceci peut rendre vos fichiers incompatibles avec les systèmes qui nécessitent une BOM (BOM veut dire Byte Ordrer Mark, indicateur d'ordre des octets).

23-1-2. Droits d'accès

Les systèmes de fichiers donnent accès aux fichiers, aux programmes avec certains droits. Les droits d'accès sont aussi importants pour l'intégrité des données que pour les performances.

Quand il s'agit de lire, autoriser plusieurs programmes à lire depuis le même fichier améliore les performances parce qu'aucun programme n'a à attendre que les autres finissent leur lecture. En revanche, quand il s'agit d'écrire, un seul programme devrait être autorisé à écrire dans un fichier donné, sinon les programmes pourraient remplacer les données des autres programmes.

23-1-3. Ouvrir un fichier

Les flux d'entrée et de sortie standard stdin et stdout sont déjà ouverts quand les programmes démarrent. Ils sont prêts à être utilisés.

En revanche, les fichiers doivent d'abord être ouverts en indiquant leur nom et les droits d'accès nécessaires.

23-1-4. Fermer un fichier

Tout fichier qui a été ouvert par un programme doit être fermé quand le programme a fini de l'utiliser. Dans la plupart des cas, les fichiers n'ont pas besoin d'être fermés explicitement, ils sont fermés automatiquement quand les objets File sont détruits automatiquement :

 
Sélectionnez
if (uneCondition) {
 
   // On suppose qu'un objet File a été créé et utilisé ici.
   // ...
 
} // ← Le fichier sera fermé automatiquement ici en sortie
  //   de la structure if. Pas besoin de le fermer explicitement.

Dans certains cas, il peut être nécessaire qu'un objet File soit rouvert pour accéder à un fichier différent ou au même fichier avec des droits d'accès différents. Dans de tels cas, le fichier doit être fermé et ensuite rouvert :

 
Sélectionnez
fichier.close();
fichier.open("enregistrements_etudiants", "r");

23-1-5. Écrire et lire un fichier

Comme les fichiers sont des flux de caractères, les fonctions d'entrée et de sortie writeln, readf, etc. sont utilisées exactement de la même manière avec eux. La seule différence est que le nom de la variable File suivi d'un point doit être ajouté :

 
Sélectionnez
writeln("bonjour");         // écrit sur la sortie standard
stdout.writeln("bonjour");  // même chose que la ligne précédente
fichier.writeln("bonjour"); // écrit dans un fichier spécifique

23-1-6. eof() pour tester la fin du fichier

La méthode eof() détermine si la fin du fichier a été atteinte pendant la lecture du fichier. Quand c'est le cas, elle retourne true.

Par exemple, la boucle suivante sera exécutée jusqu'à la fin du fichier :

 
Sélectionnez
while (!fichier.eof()) {
   /* ... */
}

23-1-7. Le module std.file

Le module std.file contient des fonctions et des types qui sont utiles pour travailler avec le contenu des dossiers. Par exemple, la fonction exists peut être utilisée pour savoir si un fichier ou un dossier existe sur le système de fichiers :

 
Sélectionnez
import std.file;
 
// ...
 
   if (exists(nomFichier)) {
      // Il y a un fichier ou un dossier qui porte ce nom
 
   } else {
      // Aucun fichier ou dossier portant ce nom
   }

23-2. La structure std.stdio.File

File utilise les mêmes caractères de mode que ceux qui sont utilisés par la fonction fopen du langage C.

Mode

Définition

r

Accès en lecture. Le fichier est ouvert et lu depuis le début.

r+

Accès en lecture et en écriture. Le fichier est ouvert pour être lu et écrit depuis le début.

w

Accès en écriture. Si le fichier n'existe pas, un fichier vide est créé. S'il existe déjà, son contenu est écrasé.

w+

Accès en lecture et en écriture. Si le fichier n'existe pas, un fichier vide est créé. S'il existe déjà, son contenu est écrasé.

a

Accès en ajout. Si le fichier n'existe pas, un fichier vide est créé. Si le fichier existe déjà, son contenu est conservé. Les données seront écrites à la fin du fichier.

a+

Accès en lecture et en ajout. Si le fichier n'existe pas, un fichier vide est créé. Si le fichier existe déjà, son contenu est conservé et le fichier est ouvert pour être lu au début et écrit à la fin.

Un caractère 'b' peut être ajouté à la chaîne de mode, comme dans "rb". Ceci peut avoir un effet sur les plateformes qui supportent le mode binaire, mais il est ignoré sur tous les systèmes POSIX.

La structure File est comprise dans le module std.stdio.

23-3. Écrire dans un fichier

Le fichier doit avoir été ouvert dans un des modes d'écriture :

 
Sélectionnez
void main()
{
   File fichier = File("enregistrements_etudiants", "w");
 
   fichier.writeln("Nom    : ", "Zafer");
   fichier.writeln("Numéro : ", 123);
   fichier.writeln("Classe : ", "1A");
}

Comme vous devez vous rappeler depuis le chapitre sur les chainesChaînes de caractères le type des littéraux tels que « enregistrements_etudiants » est string, qui consiste en une suite de caractères immuables. Pour cette raison, il n'est pas possible de construire des objets File à partir d'un nom mutable (par exemple char[]).

Le programme ci-dessus crée ou remplace le contenu d'un fichier nommé enregistrements_etudiants dans le dossier dans lequel il a été lancé (le dossier de travail du programme).

Les noms de fichiers peuvent contenir n'importe quel caractère autorisé par le système de fichiers. Pour être portable, je n'utiliserai que des caractères ASCII.

23-4. Lire un fichier

Le fichier doit avoir été ouvert dans un des modes de lecture :

 
Sélectionnez
import std.stdio;
import std.string;
 
void main()
{
   File fichier = File("enregistrements_etudiants", "r");
 
   while (!fichier.eof()) {
      string ligne = chomp(fichier.readln());
      writeln("ligne lue -> |", ligne);
   }
}

Le programme ci-dessus lit toutes les lignes du fichier nommé enregistrements_etudiants et affiche ces lignes dans la sortie standard.

23-5. Exercice

Écrire un programme qui demande un nom de fichier à l'utilisateur, ouvre ce fichier, et écrit toutes les lignes non vides de ce fichier dans un autre fichier. Le nom du nouveau fichier peut être basé sur le nom du fichier original. Par exemple, si le nom du fichier original est foo.txt, le nouveau fichier peut être appelé foo.txt.out.

La solutionFichiers - Correction.


précédentsommairesuivant