Question 165

Comment lire rapidement un fichier texte ?

Introduction

Pour lire le contenu d'un fichier texte, la méthode classique consiste à ouvrir le fichier en "input" puis à lire le fichier ligne par ligne grâce à l'instruction "Line Input".

Même si cette méthode est tout à fait utilisable et viable, elle présente l'inconvénient d'être peu performante, ce qui peut être gênant en particulier lorsqu'un programme doit traiter de gros fichiers (plusieurs dizaines ou centaines de milliers de lignes).

La lecture binaire avec Get

Une méthode très efficace consiste à lire le fichier d'un seul bloc, en l'ouvrant en mode binaire et en lisant le contenu grâce à l'instruction Get. On sépare ensuite les lignes grâce à l'instruction Split().

Exemple d'implémentation

Le code suivant présente une implémentation de lecture binaire, ainsi qu'un exemple d'utilisation


' Cette fonction lit le contenu du fichier szFileName et retourne
' ce contenu. En cas d'erreur, elle retourne une chaîne vide et
' renseigne le code d'erreur et la description de l'erreur
'
Private Function ReadFileToBuffer(ByVal szFileName As String, _
                                 ByRef errCode As Integer, _
                                 ByRef errString As String) As String
    Dim f As Integer
    Dim Buffer As String

    ' trappe les erreurs
    On Error GoTo ReadFileToBuffer_ERR

    ' Ouverture du fichier en 'Binary'
    f = FreeFile
    Open szFileName For Binary As #f
        ' préallocation d'un buffer à la taille du fichier
        Buffer = Space$(LOF(f))
        ' lecture complète du fichier
        Get #f, , Buffer
    Close #f
    ReadFileToBuffer = Buffer
ReadFileToBuffer_END:
    Exit Function
    
ReadFileToBuffer_ERR:
    ' Gestion d'erreur
    ReadFileToBuffer = ""
    errCode = Err.Number
    errString = Err.Description
    Resume ReadFileToBuffer_END
End Function

L'utilisation est très simple, de même que la récupération du contenu dans un tableau :

    Dim fileName As String
    Dim errCode As Integer
    Dim errString As String
    Dim fileContent As String
    Dim t() As String
    Dim nbLines As Long

    fileName = "C:\scanit\data\psc\ubsw\sourcedata\etc\psc\win32\giexp.tab.huge"
    
    fileContent = ReadFileToBuffer(fileName, errCode, errString)
        
    If errCode = 0 Then
        
        ' Découpage en lignes
        t() = Split(fileContent, vbCrLf)
        
        ' calcul du nombre de lignes et affichage
        nbLines = UBound(t()) + IIf(LBound(t()) = 0, 1, 0)
        MsgBox "Nombre de Lignes : " & nbLines
    Else
        ' Erreur rencontrée, affichage
        MsgBox "Erreur lors de la lecture. Code : " & errCode & ". Description : " & errString
    End If

Performances et remarques

Cette méthode est 4 à 5 fois plus rapide que la méthode naïve de lecture ligne à ligne. Un autre avantage est que cette fonction de lecture peut être utilisée pour lire des fichiers au format Unix (les fins de lignes étant représentés par LF au lieu de CRLF) : Il suffit alors de « splitter » le fichier en lignes en utilisant vbLf en lieu et place de vbCrLF, dans la fonction Split(). D'une façon générale, on peut l'utiliser pour lire tout type de fichier, pour autant que l'on dispose d'informations permettant d'exploiter utilement le contenu lu.

L'instruction Put est la symétrique de Get, elle permet d'écrire d'un seul coup le contenu d'un buffer dans un fichier ouvert en mode binaire. La fonction Join() est l'inverse de Split(), elle permet de rassembler les lignes d'un tableau en un seul buffer. Ainsi, en utilisant Join() et Put, il est simple de réécrire le fichier, après modifications éventuelles des lignes du tableau ; On a donc ainsi à peu de frais un mini éditeur de texte !

Prise en charge des très grands fichiers

Pour les très gros fichiers (plusieurs centaines de mégaoctets), l'allocation par Space$() peut poser problème : limite de taille, performances. Pour ces cas particuliers, on pourra se tourner vers l'utilisation d'une technique extrêmement performante : Le File Mapping. La description de cette technique dépasse nettement le cadre de cet article, mais la documentation Microsoft sur le sujet est bien faite. Des exemples sont disponibles à partir de ce lien : CreateFileMapping.

Pour aller Plus loin

Voir aussi :

Date de publication : 13 septembre 2007
Dernière modification : 06 mars 2008
Rubriques : Fichiers & dossiers
Mots-clés : Lire, lecture, fichier, texte, open, binaire, binary, Get, Split, Lof, Unix, rapide, File Mapping