IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Comment lire la dernière ligne d'un fichier text.


Sujet :

Delphi

  1. #21
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    et avec le mien ??

  2. #22
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Salut vous tous.
    J'aimerais dire avant toute chose que le code de Edam est le plus rapide.
    J'ai retravaillé ma fonction pour m'approcher le plus possible de ses performances
    mais il en m'en manque encore un peu.

    J'ai l'impression que c'est l'utilisation de LastDelimiter() qui me pénalise.

    voilà la methode de Edam (modifier pour en faire une fonction comparable)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    //== solution par Edam ==
    function LastText(FileName:string):string;
    var
        f:file of byte;
        s,m:string;
        t,j:integer;
        b,bb:Boolean;
    Function Dechiffre:Boolean;
    var
        i,j:integer;
        n:string;
    begin
         n:=m;
         j:=length(m);
         i:=j;
         while (j>0) and (n[j]<>#10) do dec(j);
         result:=(j>0);
         if result then
           begin
             i:=i-j;
             setlength(m,i);
             inc(j);
             move(n[j],m[1],i);
           end;
    end;
    begin
         assignfile(f,FileName);
         {$i-}
         reset(f);
         if IOResult<>0 then exit;
         t:=filesize(f);
         s:='';
         b:=false;bb:=false;
         repeat
           t:=t-$400;
           if t<0 then t:=0;
           seek(f,t);
           setlength(m,$400);
           BlockRead(f,m[1],$400,j);
           if not bb then
             begin
                while (j>0) and ((m[j]=#10) or (m[j]=#13)) do dec(j);
                bb:=j>0;
             end;
           if bb then
             begin
               if j<$400 then setlength(m,j);
               b:=Dechiffre;
               s:=m+s;
             end;
         until (b) or (t=0);
         CloseFile(f); // Ajout par EB
         result:=s;
    end;
    À noter que j'ai ajouté un CloseFile...

    Et Voici mon code retravaillé...simplifié...mieux écrit etc...
    et ce pour tenter de rejoindre en vain les performances du code de Edam.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    //==============================================================================
    //== Obtient la derniere Ligne d'un fichier texte.
    //== la derniere ligne doit être plus petite que 1022 caractères
    //== Option: SkipLastEmptyLine=TRUE
    //==         Retourne alors l'avant dernière ligne si le fichier termine
    //==         par un CRLF
    //== Une erreur : "I/0 error 103" arrive si le fichier n'existe pas.
    //== La fonction appelante doit donc faire la vérification de l'existance
    //== des fichiers.
    function GetLastLn(TextFileName:string;SkipLastEmptyLine:boolean=FALSE):string;
    const
        BUFF_SIZE=1024;
        CRLF= #13+#10;
    var
        size : Cardinal;
        f: file of byte; //Plus rapide que char!
        LastPosCRLF:Cardinal;
        TempStr:string;
    begin
        result:='';
        SetLength(TempStr,BUFF_SIZE);
        AssignFile(f, TextFileName);
        try
            Reset(f);
            size := FileSize(f);
            if size<>0 then
            begin
                if size>BUFF_SIZE then Seek(f,size-BUFF_SIZE);
                BlockRead(  f,TempStr[1],BUFF_SIZE,size);
                SetLength(TempStr,size);
                if (SkipLastEmptyLine=TRUE) and (strcomp(@TempStr[size-1],CRLF)=0) then
                    TempStr:=Copy(TempStr,1,size-2); // Remove last CRLF if need
                LastPosCRLF:=LastDelimiter(CRLF,TempStr);
                if LastPosCRLF<>0 then
                    result:=PChar(@TempStr[LastPosCRLF+1])
                else
                    result:=TempStr;
            end;
        finally
            CloseFile(f);
        end;
    end;
    Les tests effectués sont les suivants:
    Fichier texte d'evirons 17Mb
    Nombre d'appele: 100 000 fois
    Delphi 5.
    Score:

    [Edam-File of Byte] 6.50 secondes
    [EB-File of Byte] 6.56 secondes
    [EB-avec TFileStream] 7.05 secondes
    [Sub-0 TFileStream] 8.72 secondes

    Mes Conclusions:
    File of byte est plus rapide que File of Char.
    File of Char est plus rapide que l'utilisation d'un TFileStream.

    à noter que Ce sont là tous des codes très rapides si
    on considère que ca prend 100 000 call pour en mesurer les
    différences.

    C'est vrai que le code pour faire la mesure n'est pas très précis
    mais ca donne quand même une idée correcte des performances:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    procedure TForm1.Button1Click(Sender: TObject);
    const
        NbrCall=100000;
    var
     lastLn1:string;
     lastLn2:string;
     lastLn3:string;
     lastLn4:string;
     TimeStart:TDateTime;
     TimeStop:TDateTime;
     i:integer;
     convert:extended;
    begin
        RichEdit1.Lines.Clear;
        convert:=60*60*24;
        TimeStart:=Now();
        for i:=0 to NbrCall do
            lastLn1:=GetLastLn('C:\test.txt',FALSE);
        TimeStop:=Now();
        RichEdit1.Lines.Add(lastLn1+'[EB-File of Byte] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes');
        self.Refresh;
     
        //Memcode sauf que j'utilise TFileStream
        TimeStart:=Now();
        for i:=0 to NbrCall do
            lastLn2:=GetLastLn2('C:\test.txt',FALSE);
        TimeStop:=Now();
        RichEdit1.Lines.Add(lastLn2+' [EB-TFileStream] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes');
        self.Refresh;
     
        TimeStart:=Now();
        for i:=0 to NbrCall do
            lastLn3:=LastText('C:\test.txt');
        TimeStop:=Now();
        RichEdit1.Lines.Add(lastLn3+'[Edam] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes');
        self.Refresh;
     
        TimeStart:=Now();
        for i:=0 to NbrCall do
            lastLn4:=GetLastRow('C:\test.txt');
        TimeStop:=Now();
        RichEdit1.Lines.Add(lastLn4+' [Sub-0] '+FormatFloat('0.00',(TimeStop-TimeStart)*convert)+' secondes');
        self.Refresh;
    end;
    Finalement Edam

  3. #23
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 321
    Points : 88
    Points
    88
    Par défaut
    Hallo,
    edam, ne sois pas tu m'as fait aussi très plaisir en postant une solutions.
    Le seul probleme que j'ai eu, c'était de ne pas avoir compris très bien ton code,
    par example de mettre dans la function.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Function Dechiffre:Boolean;  // ce si je n'ai pas compris!
    Je suis débutant et j'essaie de comprendre ce que je fait...(pas toujours!)
    En tout cas, j'ai un très grand respect à tous ceux qui poste pour aider les autres. Car dans ce monde on se fait pas toujours aider!
    Croyez moi le plaisire que j'ai si j'ai une réponse à mon problème.
    Salutations et très bon Weekend à tous.
    Ardely

  4. #24
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    Dechiffre est une fonction (fonction privé à son conteneur "GetLastRow"; si j'ose dire ) dans la procedure où il est déclaré. c'est autorisé en delphi.
    bien sûr je peut la déclaré dehor mais pour ne pas ajouté des pramétres à sa déclaration; en plus ij'en ai besoin que pour la Function GetLastRow

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Function Dechiffre:Boolean;
    var
        i,j:integer;
        n:string;
    begin
         n:=m;
         j:=length(m);
         i:=j;
         while (j>0) and (n[j]<>#10) do dec(j);
         result:=(j>0);
         if result then
           begin
             i:=i-j;
             setlength(m,i);
             inc(j);
             move(n[j],m[1],i);
           end;
    end;

  5. #25
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    Citation Envoyé par Ardely
    Le seul probleme que j'ai eu, c'était de ne pas avoir compris très bien ton code,
    par example de mettre dans la function.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Function Dechiffre:Boolean;  // ce si je n'ai pas compris!
    alors pour qoi tu n'as pas posé la question
    Citation Envoyé par Ardely
    Je suis débutant et j'essaie de comprendre ce que je fait...(pas toujours!)
    ne somme tous passé par là sauf bilguite
    Citation Envoyé par Ardely
    En tout cas, j'ai un très grand respect à tous ceux qui poste pour aider les autres. Car dans ce monde on se fait pas toujours aider!
    tt le monde ici pour sa, donner et apprendre
    Citation Envoyé par Ardely
    Croyez moi le plaisire que j'ai si j'ai une réponse à mon problème.
    Salutations et très bon Weekend à tous.
    Ardely
    alors, pose tes questions (convenablement et aprés recherche) et ne quitte pas ton poste qu'aprés tt compris,, ok?

  6. #26
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 321
    Points : 88
    Points
    88
    Par défaut
    Hallo, Pour avancer et pour mieux comprendre pourrais-tu s.v.p me donné une petite explication de cette fonction qui est introduite dans la fonction 'LastText'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Function Dechiffre:Boolean;
    Merci et salutations

  7. #27
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Function Dechiffre:Boolean;
    var
        i,j:integer;
        n:string;
    begin
         n:=m;
         j:=length(m);
         i:=j;
         while (j>0) and (n[j]<>#10) do dec(j);// recherche de chr(10) à partir de la fin de string(n)
         result:=(j>0);
         if result then 
           begin
             i:=i-j;
             setlength(m,i);
             inc(j);
             move(n[j],m[1],i);
           end;  // si le trouve il coupie les caractére à partir de chr(10) trouvé jusqu'à la fin de string où en a cherché
    end;
    dans ma procedure je lis a partir de fin de fichier des bloc de $400 byte ; et ma function dechiffre ne fais que cherché si le caratére de fin de lin (lin qui précéde le dérnier) est touvé si non en lis un autre bloc et insi de suite et en cumule tout
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
               b:=Dechiffre;
               s:=m+s;
    bah je suis pas doué dans les explications mais j'éspére que sa suffira? si tu veux je détaille plus (même si ce sera une grand punition pour déposé un code )

  8. #28
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    La fonction Pos (ou AnsiPos) ne ferait-elle pas la même chose ?
    [EDIT]
    Ah non, je suis bête : Elle recherche la 1ère occurence... pas la dernière. Il faudrait alors faire une ReverseString() avant d'analyser la chaine, puis inverser le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Result := Abs(Pos(#10#13, ReverseString(str)) - Length(str));
    Bref, j'ai rien dis.
    à+

  9. #29
    Membre régulier
    Inscrit en
    Novembre 2006
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 321
    Points : 88
    Points
    88
    Par défaut
    Ah, enfin, je viens de comprendre maintenant cette fonctionnalité dans une fonction. Maintenant je vois l'intérêt et le parcours à ce bon résultat,
    Merci edam

  10. #30
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    pas de quoi

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Lire les 20 dernières lignes d'un fichier texte
    Par David_24 dans le forum Tcl/Tk
    Réponses: 1
    Dernier message: 25/05/2009, 17h47
  2. Réponses: 1
    Dernier message: 27/04/2009, 19h04
  3. Lire une les 3 dernières ligne d'1 fichier texte
    Par BECHE dans le forum Langage
    Réponses: 2
    Dernier message: 08/02/2009, 14h38
  4. Réponses: 6
    Dernier message: 22/09/2008, 14h52
  5. Comment lire une seul ligne d'un fichier texte?
    Par Julien1987 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 18/01/2007, 13h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo