Astuces de recherche...
Home
- Accueil & nouveautés
- Les newsgroups VB
- Téléchargements
- L'équipe
- Nous contacter
- Liens
Rubriques
- Toutes les questions
- Affichage & graphismes
- Algorithmique
- API
- Base de registre
- Bases de données
- Contrôles
- Date & heure
- Déploiement
- Divers
- Erreurs & problèmes
- Fichiers & dossiers
- Généralités
- Impression
- Internet & mails
- Math
- Multimédia
- Réseaux
- Structures de données
- Texte & strings
- VB .Net
- VB Script
- VBA
- Windows

Question 164

Comment enregistrer et relire un tableau ?

Cet article présente diverses façons de récupérer ou de sauvegarder un tableau de données à partir d'un fichier. Il est inadapté au cas où il s'agit simplement de modifier quelques valeurs d'un fichier et que l'on n'a pas besoin de toutes les valeurs.

Les données du tableau sont dans un fichier dont le nom est contenu dans la variable String Fichier (chemin d'accès inclus). Dans tous les cas, on connaît le type des éléments du tableau. Les premiers exemples utilisent des nombres réels (Double).

Premier cas : les données (réels) sont dans un fichier texte, nombre de données connu

12.356
-2.85
.../...

 Dim T(1 To 100) As Double, I As Integer, f As Integer
    'lecture des données
    f = FreeFile
    Open Fichier For Input As #f
        For I = 1 To 100
            Input #f, T(I)
        Next I
    Close #f

    '.../...
    
    'écriture des données
    f = FreeFile
    Open Fichier For Output As #f
        For I = 1 To 100
            Write #f, T(I)
        Next I
    Close #f

Avantage de la méthode : simple à comprendre

Désavantages : il faut connaître le nombre de valeurs stockées, il peut y avoir des problèmes de lecture liés aux paramètres nationaux (point ou virgule), on transforme implicitement un String en double ce qui n'est pas très propre ... mais autorisé par VB. Il faut lire les données une par une.

Deuxième cas : les données sont stockées dans un fichier binaire, nombre de données connu

 Dim T(1 To 100) As Double, I As Integer, f As Integer
    'lecture des données
    f = FreeFile
    Open Fichier For Binary As #f
        For I = 1 To 100
            Get #f, , T(I)
        Next I
    Close #f

    '.../...
    
    'écriture des données
    f = FreeFile
    Open Fichier For Binary As #f
        For I = 1 To 100
            Put #f, , T(I)
        Next I
    Close #f

Remarque :

Get #f,,<valeur à lire>
Put #f,,<valeur à écrire>

permettent respectivement de lire et écrire les valeurs une par une. Il serait équivalent, mais plus long (évaluation de I à chaque passage) d'écrire

Get #f,I,<valeur à lire>
Put #f,I, <valeur à écrire>

Avantages de la méthode : simplicité, pas de problèmes liés aux paramètres nationaux, pas de transtypage, taille du fichier beaucoup plus petite a priori (pas toujours vrai)

Désavantages : pas de relecture directe en mode texte. Il faut lire les données une à une. Il faut connaître le nombre d'élément

Troisième cas : fichier binaire, nombre de données connu, le tableau est lu en une fois

 Dim T(1 To 100) As Double, f As Integer
    'lecture des données
    f = FreeFile
    Open Fichier For Binary As #f
        Get #f, , T
    Close #f

    '.../...
    
    'écriture des données
    f = FreeFile
    Open Fichier For Binary As #f
        Put #f, , T
    Close #f

Avantages : rapidité d'exécution

Désavantage : il faut connaître le nombre d'éléments

Quatrième cas : fichier binaire, le nombre d'éléments est inconnu

On doit utiliser un tableau dynamique dont la dimension n'est pas fournie dans la déclaration, pour trouver cette dimension on a besoin d'une variable auxiliaire du même type que le tableau

 Dim T() As Double, X As Double, f As Integer
    'lecture des données
    f = FreeFile
    Open Fichier For Binary As #f
        ReDim T(1 To LOF(f) / Len(X))
        Get #f, , T
    Close #f

    '.../...

    'écriture des données
    f = FreeFile
    Open Fichier For Binary As #f
        Put #f, , T
    Close #f

    '.../...

    'Bien penser à libérer la mémoire occupée par la variable T
    Erase T

LOF(f) renvoie le nombre d'octets du fichier (length of file)
Len(X) renvoie le nombre d'octets utilisés par le type de la variable X

Avantage : on n'a pas besoin de connaître le nombre de données.

Désavantage : si on se trompe dans le type (long à la place d'integer par exemple) on n'aura pas du tout le même tableau.

Cette méthode s'utilise quand on est sûr du contenu du fichier de données. Elle peut aussi servir pour lire le contenu binaire d'un fichier dans un tableau de bytes. Tous les octets, même ceux représentant des caractères non affichables, seront dans le tableau.

 Dim T() As Byte, f As Integer
    'lecture des données
    f = FreeFile
    Open Fichier For Binary As #f
        ReDim T(1 To LOF(f))
        Get #f, , T
    Close #f

Cinquième cas : fichier binaire, nombre d'éléments inconnu, type utilisateur

Ce type ne doit pas comporter de champs de type chaîne de caractères

L'exemple utilise un type MesPoints et un type MesRectangles définis de la façon suivante

Type MesPoints
    X As Double
    Y As Double
End Type

Type MesRectangles
    HautGauche As MesPoints
    BasDroit As MesPoints
End Type  

 Dim T() As Double, X As MesRectangles, f As Integer
    'lecture des données
    f = FreeFile
    Open Fichier For Binary As #1
        ReDim T(1 To LOF(f) / Len(X))
        Get #f, , T
    Close #f

    '.../...
    

    'écriture des données
    f = FreeFile
    Open Fichier For Binary As #f
        Put #f, , T
    Close #f

    '.../...

    'Bien penser à libérer la mémoire occupée par la variable T
    Erase T

Ici Len(X) vaut quatre fois le nombre d'octets utilisés par un double car le type Rectangle utilise deux types points qui utilisent eux-mêmes deux types double. On constate qu'il n'est pas nécessaire de connaître cette taille pour faire fonctionner le programme

Avantage : on n'a pas besoin de connaître le nombre de données

Sixième cas : les données de chaînes, nombre de données inconnu

Une solution est explicitée dans l'article Comment lire rapidement un fichier texte ?

On peut bien entendu se reporter au cas 1, mais il faut connaître le nombre d'éléments ou lire le fichier jusqu'à la fin ligne par ligne.

On peut aussi utiliser la fonction split et un séparateur qui n'apparaît pas dans les données, par exemple ici le caractère "&" (on pourrait prendre tout aussi bien la chaîne "<séparateur>")

 Const Sep As String = "&"
 Dim T() As String, X As String, I As Integer, f As Integer
    'lecture des données
    
    f = FreeFile
    Open Fichier For Input As #f
        Input #f, X
        T = Split(X, Sep)
    Close #f

    '.../...

    'écriture des données
    X = T(0)
    For I = 1 To UBound(T)
        X = X & Sep & T(I)
    Next I
    f = FreeFile
    Open Fichier For Output As #f
        Print #f, X
    Close #f

    '.../...

    'Bien penser à libérer la mémoire occupée par la variable T
    Erase T

La fonction split renvoie un tableau commençant à zéro et qui contient un élément de plus que la chaîne de caractères comporte de séparateurs. Ainsi, pour X="un&deux&trois&quatre", l'appel à split renverra T=["un","deux","trois","quatre"] et T(1) vaut "deux". De même, split appliqué à X="&un&" renverra T=["","un",""] et T(2)=""

Avantage : on n'a pas besoin de connaître le nombre de données

Voir aussi :

Date de publication : 13 septembre 2007
Dernière modification : 13 septembre 2007
Rubriques : Fichiers & dossiers
Mots-clés : tableaux, tableaux dynamiques, fichiers, lecture, écriture, type utilisateur, enregistrer, sauvegarder, array