15.6. Les flux d'entrée / sortie sur fichiers

Les classes d'entrée / sortie sur les fichiers sont implémentées de manière similaire aux classes d'entrée / sortie sur les chaînes de caractères, à ceci près que leurs méthodes spécifiques permettent de manipuler un fichier au lieu d'une chaîne de caractères. Ainsi, la classe basic_ofstream dérive de basic_ostream, la classe basic_ifstream de la classe basic_istream, et la classe basic_fstream de la classe basic_iostream. Toutes ces classes sont déclarées dans l'en-tête fstream. Vous trouverez à titre d'exemple la déclaration de la classe basic_ofstream tel qu'il apparaît dans cet en-tête :

template <class charT,
    class traits = char_traits<charT> >
class basic_ofstream : public basic_ostream<charT, traits>
{
public:
// Les types de données :
    typedef charT                     char_type;
    typedef typename traits::int_type int_type;
    typedef typename traits::pos_type pos_type;
    typedef typename traits::off_type off_type;

// Les constructeurs et destructeurs :
    basic_ofstream();
    explicit basic_ofstream(const char *nom,
        ios_base::openmode mode = ios_base::out | ios_base::trunc);

// Les méthodes de gestion du fichier :
    basic_filebuf<charT, traits> *rdbuf() const;
    bool is_open();
    void open(const char *nom, ios_base::openmode mode = out | trunc);
    void close();
};

Comme pour les flux d'entrée / sortie sur les chaînes de caractères, il est possible d'initialiser le flux dès sa construction ou a posteriori. Les méthodes importantes sont bien entendu la méthode open, qui permet d'ouvrir un fichier, la méthode is_open, qui permet de savoir si le flux contient déjà un fichier ouvert ou non, et la méthode close, qui permet de fermer le fichier ouvert.

Exemple 15-10. Utilisation de flux d'entrée / sortie sur un fichier

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void)
{
    // Lit les données :
    int i;
    double d, e;
    cout << "Entier Réel Réel : ";
    cin >> i >> d >> e;
    // Enregistre ces données dans un fichier :
    ofstream f("fichier.txt");
    if (f.is_open())
    {
        f << "Les données lues sont : " <<
            i << " " << d << " " << e << endl;
        f.close();
    }
    return 0;
}

Note : Il est important de bien noter que le destructeur des flux ne ferme pas les fichiers. En effet, ce sont les tampons utilisés de manière sous-jacente par les flux qui réalisent les opérations sur les fichiers. Il est même tout à fait possible d'accéder à un même fichier avec plusieurs classes de flux, bien que cela ne soit pas franchement recommandé. Vous devrez donc prendre en charge vous-même les opérations d'ouverture et de fermeture des fichiers.

Bien entendu, les classes de flux permettant d'accéder à des fichiers héritent des méthodes de positionnement de leurs classes de base. Ainsi, les classes de lecture dans un fichier disposent des méthodes tellg et seekg, et les classes d'écriture disposent des méthodes tellp et seekp. Ces opérations permettent respectivement de lire et de fixer une nouvelle valeur du pointeur de position du fichier courant.

Exemple 15-11. Repositionnement du pointeur de fichier dans un flux d'entrée / sortie

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void)
{
    // Ouvre le fichier de données :
    fstream f("fichier.txt",
        ios_base::in | ios_base::out | ios_base::trunc);
    if (f.is_open())
    {
        // Écrit les données :
        f << 2 << " " <<  45.32 << " " << 6.37 << endl;
        // Replace le pointeur de fichier au début :
        f.seekg(0);
        // Lit les données :
        int i;
        double d, e;
        f >> i >> d >> e;
        cout << "Les données lues sont : " <<
            i << " " << d << " " << e << endl;
        // Ferme le fichier :
        f.close();
    }
    return 0;
}

Note : Les classes d'entrée / sortie sur fichier n'utilisent qu'un seul tampon pour accéder aux fichiers. Par conséquent, il n'existe qu'une seule position dans le fichier, qui sert à la fois à la lecture et à l'écriture.