Lecture séquentielle de fichier texte

L’on est parfois amené à faire des traitements sur un grand nombre de fichiers textes (pour faire des statistiques, extraire des données, modifier une valeur, …). Pour cela, le premier réflexe est d’utiliser les fonctions standard de lecture proposées par le WLangage. Le code ci-dessous propose d’augmenter la vitesse de lecture de vos fichiers en remplaçant le fLitLigne par la lecture d’un buffer et la recherche de retour-charriot.

sFichiers,sFichier,sLigne,sBuffer sont des chaînes
f,nNumFichier,nMaxFichier,nRC,nTaille,nLu,nLigne sont des entiers
nTailleBuffer est un entier = 1000    //1000 semble être la meilleure valeur
 
sFichiers=fListeFichier("IciVotreRépertoire"+["\"]+"*.csv",frNonRécursif)
nMaxFichier=ChaîneOccurrence(sFichiers,RC)+1
 
POUR TOUTE CHAINE sFichier DE sFichiers SEPAREE PAR RC
  nNumFichier++;Jauge(nNumFichier,nMaxFichier,"fichier : "+nNumFichier+" / "+nMaxFichier)
  Multitâche(-1)
  nTaille=fTaille(sFichier)  //servira de comparaison par la suite
  SI nTaille>0 ALORS
    f=fOuvre(sFichier,foLecture)
    SI f<>-1 ALORS
//      ChronoDébut()  //pour tester la rapidité
      nLigne=0
      sBuffer=fLit(f,nTailleBuffer);nLu=Taille(sBuffer)
      TANTQUE sBuffer>""
        nRC=Position(sBuffer,RC)
        SI nRC < 1 ALORS
          sLigne=sBuffer;sBuffer=""
        SINON
          sLigne=Gauche(sBuffer,nRC-1);sBuffer=Milieu(sBuffer,nRC+2)
        FIN
        TANTQUE sLigne<>EOT
          nLigne++
 
          //=================================
          //ici traitement de la ligne
          //=================================
 
          SI sBuffer="" ALORS SORTIR
          nRC=Position(sBuffer,RC)
          SI nRC < 1 ALORS
            SI nLu < nTaille ALORS SORTIR//pour y ajouter un autre buffer, sinon c'est la dernière ligne à traiter
            sLigne=sBuffer;sBuffer=""
          SINON
            sLigne=Gauche(sBuffer,nRC-1);sBuffer=Milieu(sBuffer,nRC+2)
          FIN
        FIN
        SI nLu=nTaille ALORS SORTIR
        sLigne=fLit(f,nTailleBuffer);nLu+=Taille(sLigne);sBuffer+=sLigne
      FIN
      fFerme(f)
//      Trace(ChronoFin+TAB+nLigne)
    FIN
  FIN
FIN

À comparer au code classique

POUR TOUTE CHAINE sFichier DE sFichiers SEPAREE PAR RC
  nNumFichier++;Jauge(nNumFichier,nMaxFichier,"fichier : "+nNumFichier+" / "+nMaxFichier)
  Multitâche(-1)
  nTaille=fTaille(sFichier)
  SI nTaille>0 ALORS
    f=fOuvre(sFichier,foLecture)
    SI f<>-1 ALORS
//      ChronoDébut()
      nLigne=0
      sLigne=fLitLigne(f)
      TANTQUE sLigne<>EOT
        nLigne++
        //=================================
        //ici traitement de la ligne
        //=================================
        sLigne=fLitLigne(f)
      FIN
      fFerme(f)
//      Trace(ChronoFin+TAB+nLigne)
    FIN
  FIN
FIN

Après un test sur 500 fichiers de 1ko à 10Mo, totalisant 210Mo, mis sur un disque dur local mécanique (Intel I5 / Windows 7 / 32bits), la lecture grâce au code en haut est globalement 36.5% plus rapide que le code classique du bas.