Sequential reading of text file

It is sometimes necessary to make treatments on a large number of text files (to make statistics, to extract data, to modify a value, …). For that, the first reflex is to use the standard reading functions proposed by WLanguage. The code below proposes to increase the reading speed of your files by replacing the fReadLine by the reading of a buffer and the search of carriage-return.

sFichiers,sFichier,sLigne,sBuffer are strings
f,nNumFichier,nMaxFichier,nRC,nTaille,nLu,nLigne are int
nTailleBuffer is int = 1000    //1000 semble être la meilleure valeur
 
sFichiers=fListFile("IciVotreRépertoire"+["\"]+"*.csv",frNotRecursive)
nMaxFichier=StringCount(sFichiers,CR)+1
 
FOR EACH STRING sFichier OF sFichiers SEPARATED BY CR
  nNumFichier++;Gauge(nNumFichier,nMaxFichier,"fichier : "+nNumFichier+" / "+nMaxFichier)
  Multitask(-1)
  nTaille=fSize(sFichier)  //servira de comparaison par la suite
  IF nTaille>0 THEN
    f=fOpen(sFichier,foRead)
    IF f<>-1 THEN
      //      ChronoDébut()  //pour tester la rapidité
      nLigne=0
      sBuffer=fRead(f,nTailleBuffer);nLu=Length(sBuffer)
      WHILE sBuffer>""
        nRC=Position(sBuffer,CR)
        IF nRC < 1 THEN
          sLigne=sBuffer;sBuffer=""
        ELSE
          sLigne=Left(sBuffer,nRC-1);sBuffer=Middle(sBuffer,nRC+2)
        END
        WHILE sLigne<>EOT
          nLigne++
 
          //=================================
          //ici traitement de la ligne
          //=================================
 
          IF sBuffer="" THEN BREAK
          nRC=Position(sBuffer,CR)
          IF nRC < 1 THEN
            IF nLu < nTaille THEN BREAK//pour y ajouter un autre buffer, sinon c'est la dernière ligne à traiter
            sLigne=sBuffer;sBuffer=""
          ELSE
            sLigne=Left(sBuffer,nRC-1);sBuffer=Middle(sBuffer,nRC+2)
          END
        END
        IF nLu=nTaille THEN BREAK
        sLigne=fRead(f,nTailleBuffer);nLu+=Length(sLigne);sBuffer+=sLigne
      END
      fClose(f)
      //      Trace(ChronoFin+TAB+nLigne)
    END
  END
END

Compared to the classic code

FOR EACH STRING sFichier OF sFichiers SEPARATED BY CR
  nNumFichier++;Gauge(nNumFichier,nMaxFichier,"fichier : "+nNumFichier+" / "+nMaxFichier)
  Multitask(-1)
  nTaille=fSize(sFichier)
  IF nTaille>0 THEN
    f=fOpen(sFichier,foRead)
    IF f<>-1 THEN
      //      ChronoDébut()
      nLigne=0
      sLigne=fReadLine(f)
      WHILE sLigne<>EOT
        nLigne++
        //=================================
        //ici traitement de la ligne
        //=================================
        sLigne=fReadLine(f)
      END
      fClose(f)
      //      Trace(ChronoFin+TAB+nLigne)
    END
  END
END

After a test on 500 files from 1ko to 10Mo, totaling 210Mo, put on a local mechanical hard disk (Intel I5 / Windows 7 / 32bits), reading through the code at the top is globally 36.5% faster than the classic code of the bottom .