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 :

Lire un fichier texte rapidement


Sujet :

Delphi

  1. #1
    Aos
    Aos est déconnecté
    Membre habitué

    Profil pro
    Inscrit en
    janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 189
    Points : 184
    Points
    184
    Par défaut Lire un fichier texte rapidement
    Bonjour,

    Alors la question est simple :
    Y a-t-il plus rapide pour extraire un fichier texte complet dans un tableau que la fonction suivante sachant que celle-ci mets a peu pres 30 seconde pour extraire les 20.000 ligne de mon fichier (a peu pres 150 caractere par lignes).
    Sachant que le type tableuaInfiniDeString = array of string;

    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
    function extraireFichier(leFichier : String):tableauInfiniDeString;
    var
    F : TextFile;
    tableauTemporaire : tableauInfiniDeString;
    i : integer;
    chaine:string;
    begin
    i:=0;
    AssignFile(F,leFichier);
    reset(F);
    setLength(tableauTemporaire,0);
    while not(eof(F)) do
      begin
      setLength(tableauTemporaire,length(tableauTemporaire)+1);
      readln(F,chaine);
      tableauTemporaire[i]:=chaine;
      inc(i);
      application.ProcessMessages;
      end;
    CloseFile(F);
    extraireFichier:=tableauTemporaire;
    end;

  2. #2
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    As-tu essayé de travailler avec un TStringList et sa méthode LoadFromFile ?
    Tu devrais avoir des résultats plus rapide.

    @+

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    12 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 183
    Points : 21 480
    Points
    21 480
    Par défaut
    Quelques optimisations sont possibles, l'application.processmessages qui permet à l'application de traiter les messages, donc ralenti la lecture, les setlenght a répétition !

    Le plus simple serait une TStringList et un LoadFromFile, maintenant tu préféres peut-être les Tableaux, je ponds une fonction et je reviens

    EDIT : Griller par Claudius !

    EDIT 2 :
    Une TStringList est dix fois plus lente que la fonction suivante, fichier testé, 2 millions de ligne de 60 char,

    extraireFichier : Trop long et Mémoire Insuffisante avant 100 000 lignes
    FillArrayFromTextFile : 6533 ms
    StringList.LoadFromFile : 62483 ms

    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
    function FillArrayFromTextFile(const FileName: string): Types.TStringDynArray;
    var
      FLNC: TextFile;
      CountLn, I: Integer;
    begin
       CountLn := 0;
       AssignFile(FLNC, FileName);
       Reset(FLNC);
       try
         while not Eof(FLNC) do
         begin
           Inc(CountLn);
           Readln(FLNC);
         end;
       finally
         CloseFile(FLNC);
       end;
     
       Reset(FLNC);
       try
         SetLength(Result, CountLn);
     
         for I := 0 to CountLn - 1 do
           Readln(FLNC, Result[I]);
       finally
         CloseFile(FLNC);
       end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Aos
    Aos est déconnecté
    Membre habitué

    Profil pro
    Inscrit en
    janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 189
    Points : 184
    Points
    184
    Par défaut
    Non j'ai jamais essayer avec un TStringList mais non je n'ai pas specialement de preference pour le tableau car le traitement effectuer apres est en TStringList.

    Je teste

  5. #5
    Aos
    Aos est déconnecté
    Membre habitué

    Profil pro
    Inscrit en
    janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 189
    Points : 184
    Points
    184
    Par défaut
    waaaaaaaaaaah c'est la folie!
    J'ai juste "pour l'exemple" fait un SetLength(leTableau,50000); et donc enlever le SetLength() a repetition dans la boucle et la lecture de tout le fichier se fait quasi instantanément (une seconde ou 2).

    Faut juste que je sache la longueur du fichier pour pouvoir mettre un Setlength avec une variable maintenant.
    Avec une boucle while et un readln() et inc(i), ça devrait aller vite.
    Sauf s'il existe une méthode pour connaitre directement le nom de ligne d'un fichier texte ?

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    12 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 183
    Points : 21 480
    Points
    21 480
    Par défaut
    Normal !

    Tu as 50 000 items, il va faire une nouvelle allocation mémoire, mais 99% il n'a pas la place pour 50 001 item, donc il alloue 50 001 ailleurs, recopie les 50000 anciens et laisse le 50 001 eme pret pour une nouvelle valeur !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Héhé pas mal la méthode de Shai:

    1. Je compte le nb de lignes
    2. Je dimensionne le tableau
    3. Je remplis...

    2M de lignes en 6.5s ! Intéressant.

    [edit]
    Les résultats sont-ils aussi intéressant avec un fichier disons 2 fois plus petit ? (Je n'ai pas de fichier sous la main)
    [/edit]

    @+ Claudius

  8. #8
    Aos
    Aos est déconnecté
    Membre habitué

    Profil pro
    Inscrit en
    janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 189
    Points : 184
    Points
    184
    Par défaut
    Quel methode claudius ?

    SHAI : j'ai rien compris a ton dernier post

    Une petite precision le fichier change tout le temps, il est ramené avec un opedialog donc je ne maitrise pas le nombre de ligne. Il peut y en avoir 10, 100, 1000 ou 100.000

  9. #9
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par Aos
    Quel methode claudius ?
    Celle de Shai: FillArrayFromTextFile.

    Citation Envoyé par Aos
    Une petite precision le fichier change tout le temps, il est ramené avec un opedialog donc je ne maitrise pas le nombre de ligne. Il peut y en avoir 10, 100, 1000 ou 100.000
    La méthode de Shai dimensionne le tableau en fonction du fichier !
    Si tu regardes bien son code il parcourt 2 fois le fichier.

    @+ Claudius

  10. #10
    Aos
    Aos est déconnecté
    Membre habitué

    Profil pro
    Inscrit en
    janvier 2006
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 189
    Points : 184
    Points
    184
    Par défaut
    ah oui ok, j'avias pas vu qu'il avait edité son message
    ouais ben j'avais codé a peu pres une méthode similaire. La meme en faite
    sauf que je boucle pas jusqu'a countLn-1 mais jusqu'a pred(countLn).
    Oui je sais c'est pareil

    Merci a vous deux
    Et voila une affaire simple mais resolu!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Applet] lire un fichier texte
    Par lebesnec dans le forum Applets
    Réponses: 2
    Dernier message: 07/07/2005, 10h09
  2. Réponses: 1
    Dernier message: 24/11/2004, 16h54
  3. [Fichier] Lire un fichier texte long
    Par _Eric_ dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 18/08/2004, 15h22
  4. Réponses: 2
    Dernier message: 26/05/2004, 17h53
  5. Insertion dans fichier texte + rapide que TStringList ?
    Par benj63 dans le forum C++Builder
    Réponses: 8
    Dernier message: 26/02/2004, 11h34

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