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

Lazarus Pascal Discussion :

Trier les lignes d'un fichier texte de très grande taille par ordre croissant [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut Trier les lignes d'un fichier texte de très grande taille par ordre croissant
    Bonjour,

    J'ai un fichier texte de très grande taille (1 million de lignes environ) dans lequel je souhaite trier les lignes en ordre croissant.

    Pouvez-vous m'indiquer la meilleure méthode à utiliser pour trier les lignes de ce très volumineux fichier en ordre croissant ?

    Merci,
    ZiP

  2. #2
    Membre extrêmement actif Avatar de Jon Shannow
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    avril 2011
    Messages
    3 811
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : avril 2011
    Messages : 3 811
    Points : 7 409
    Points
    7 409
    Par défaut
    Bonjour,

    Pour ma part, je placerais ce fichier text dans un TStringList et j'utiliserais la méthode Sort.

    JS
    Au nom du pèze, du fisc et du St Estephe
    Au nom du fric, on baisse son froc...

  3. #3
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    En fait, javais peur que le fichier soit trop volumineux pour un TStringList.

    Je n'ai pas réussi à trouver d'informations concernant la capacité de cette liste.

    Merci,
    ZiP

  4. #4
    Membre extrêmement actif Avatar de Jon Shannow
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    avril 2011
    Messages
    3 811
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : avril 2011
    Messages : 3 811
    Points : 7 409
    Points
    7 409
    Par défaut
    Citation Envoyé par [ZiP] Voir le message
    En fait, javais peur que le fichier soit trop volumineux pour un TStringList.

    Je n'ai pas réussi à trouver d'informations concernant la capacité de cette liste.

    Merci,
    ZiP
    Le mieux c'est d'essayer, mais je ne pense pas que ça pose un problème.

    Par contre, ça risque de ramer, mais quelle que soit la méthode, ça ramera, vu la taille du fichier.

    JS
    Au nom du pèze, du fisc et du St Estephe
    Au nom du fric, on baisse son froc...

  5. #5
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Je vais essayer.

    Y a-t-il un moyen d'obtenir la progression de la fonction Sorted du TStringList ?

    Merci,
    ZiP

  6. #6
    Membre extrêmement actif Avatar de Jon Shannow
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    avril 2011
    Messages
    3 811
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : avril 2011
    Messages : 3 811
    Points : 7 409
    Points
    7 409
    Par défaut
    Citation Envoyé par [ZiP] Voir le message
    Je vais essayer.

    Y a-t-il un moyen d'obtenir la progression de la fonction Sorted du TStringList ?

    Merci,
    ZiP
    Je ne sais pas, j'avoue.
    Au nom du pèze, du fisc et du St Estephe
    Au nom du fric, on baisse son froc...

  7. #7
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    3 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 3 631
    Points : 10 406
    Points
    10 406
    Billets dans le blog
    6
    Par défaut
    Je ne pense pas : on ne sait pas combien d'itérations seront nécessaires...

    Par contre, on peut implémenter sa propre fonction de tri à passer à la liste, et là, rien n'empêche d'appeler une CallBack toutes les x itérations ou toutes les x millisecondes pour animer l'attente.
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  8. #8
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour,

    Mon code est assez simple :

    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
       TS : TStringList;
    begin
      if OpenDialog1.Execute then
      begin
        TS := TStringList.Create;
        TS.Sorted := true;
        TS.Duplicates := dupIgnore;
        TS.LoadFromFile(OpenDialog1.FileName);
        TS.SaveToFile(ExtractFileNameWithoutExt(OpenDialog1.FileName) + '_sorted' + ExtractFileExt(OpenDialog1.FileName));
        TS.Free;
      end;
    end;
    Pouvez-vous m'expliquer comment implémenter ma propre fonction de tri qui me permettrai d'afficher la progression ?

    Merci,
    ZiP

  9. #9
    Membre extrêmement actif Avatar de Jon Shannow
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    avril 2011
    Messages
    3 811
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : avril 2011
    Messages : 3 811
    Points : 7 409
    Points
    7 409
    Par défaut
    Regardes du coté de "customsort".


    ICI


    JS
    Au nom du pèze, du fisc et du St Estephe
    Au nom du fric, on baisse son froc...

  10. #10
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Merci, je vais regarder de ce côté !

    ZiP

  11. #11
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonsoir,

    Voici mon code :
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
         TS := TStringList.Create;
         TS.Sorted := true;
         TS.Duplicates := dupIgnore;
         ThousandSeparator := ' ';
    end;
     
    procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
    begin
         TS.Free;
    end;
     
    procedure TForm1.BViderClick(Sender: TObject);
    begin
      if MessageDlg('Confirmation', 'Voulez-vous vraiment vider la liste ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
      begin
           BVider.Enabled := false;
           BAjouter.Enabled := false;
           BSauvegarder.Enabled := false;
           TS.Clear;
           LInformations.Caption := IntToStr(TS.Count);
           BVider.Enabled := true;
           BAjouter.Enabled := true;
           BSauvegarder.Enabled := true;
      end;
    end;
     
    procedure TForm1.BAjouterClick(Sender: TObject);
    var
       F: TextFile;
       L : String;
    begin
      OpenDialog1.Filter := 'Fichier texte|*.txt';
      OpenDialog1.Options := [ofFileMustExist];
      OpenDialog1.Title := 'Veuillez choisir le fichier à ajouter...';
      if OpenDialog1.Execute then
      begin
           BVider.Enabled := false;
           BAjouter.Enabled := false;
           BSauvegarder.Enabled := false;
           AssignFile(F, OpenDialog1.FileName);
           Reset(F);
           try
              while not Eof(F) do
              begin
                ReadLn(F, L);
                TS.Add(L);
                LInformations.Caption := FloatToStrF(TS.Count, ffNumber, 10, 0);
                Application.ProcessMessages;
              end;
           except
                 on E : Exception do
                 begin
                      MessageDlg('Erreur', E.Message, mtError, [mbOK], 0);
                 end;
           end;
           CloseFile(F);
           BVider.Enabled := true;
           BAjouter.Enabled := true;
           BSauvegarder.Enabled := true;
      end;
    end;
     
    procedure TForm1.BSauvegarderClick(Sender: TObject);
    var
       F: TextFile;
       i: Integer;
    begin
         SaveDialog1.Filter := 'Fichier Texte|*.txt';
         SaveDialog1.Title := 'Veuillez choisir le nom du fichier à sauvegader...';
         if SaveDialog1.Execute then
         begin
              BVider.Enabled := false;
              BAjouter.Enabled := false;
              BSauvegarder.Enabled := false;
              AssignFile(F, SaveDialog1.FileName);
              Rewrite(F);
              try
                 for i:= 0 to TS.Count-1 do
                 begin
                   WriteLn(F, TS.Strings[i]);
                   LInformations.Caption := FloatToStrF(i+1, ffNumber, 10, 0) + ' / ' + FloatToStrF(TS.Count, ffNumber, 10, 0);
                   Application.ProcessMessages;
                   end;
              except
                    on E : Exception do
                    begin
                         MessageDlg('Erreur', E.Message, mtError, [mbOK], 0);
                    end;
              end;
              CloseFile(F);
              BVider.Enabled := true;
              BAjouter.Enabled := true;
              BSauvegarder.Enabled := true;
         end;
    end;
    Et voici l'erreur que je rencontre au bout d'un moment pendant l'ajout :



    Savez-vous comment y remédier ?

    Merci,
    ZiP

  12. #12
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour,

    J'ai ce message lorsque je compile mon programme :
    unit1.pas(152,41) Hint: Converting the operands to "Int64" before doing the add could prevent overflow errors.
    Il se trouve sur cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    LInformations.Caption := FloatToStrF(i+1, ffNumber, 10, 0) + ' / ' + FloatToStrF(TS.Count, ffNumber, 10, 0);
    J'ai essayé de passer mon i en Int64 plutôt qu'en Integer mais ça ne fonctionne plus à cause de ma boucle for.

    C'est peut-être à cause de ça que j'ai mon erreur "Out of memory" car le programme en mémoire fait environ 1Go alors que j'ai 8Go de mémoire vive et qu'il reste encore plusieurs Go de libre...

    Merci,
    ZiP

  13. #13
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    3 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 3 631
    Points : 10 406
    Points
    10 406
    Billets dans le blog
    6
    Par défaut
    Le StringList utilise l'algorithme de tri QSort, récursif => sur un gros fichier, ça doit faire sauter la pile !

    Comment sont tes données ? Très différentes, ou très semblables ? Très désordonnées, ou plutôt bien dans l'ordre ?

    Il va pê falloir diviser tes données.
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  14. #14
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonsoir,

    Merci pour l'information sur l'algorithme de tri.

    Mes données sont très différentes et très désordonnées.

    Je suis en train de développer une routine de tri personnelle, elle sera surement plus lente mais ne plantera pas

    Merci,
    ZiP

  15. #15
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonsoir,

    Je ne sais pas trop vers quelle méthode me tourner :
    1. utiliser deux fichiers, lire (avec un TextFile) le premier fichier (source) puis aller chercher la position (avec un CompareStr) de la ligne dans le second fichier (destination) et enfin l'écrire au bon endroit, j'en profite également pour retirer les doublons
    2. utiliser un tableau dynamique pour y placer mes données et faire le même traitement (trier et dédoublonner)
    3. peut-être avez vous une meilleure méthode ?

    Le fichier fait plusieurs Go avec plusieurs millions de lignes.

    Merci d'avance pour vos conseils,
    ZiP

  16. #16
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    3 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 3 631
    Points : 10 406
    Points
    10 406
    Billets dans le blog
    6
    Par défaut
    Est-ce du texte et tes lignes peuvent-elles débuter par toutes les lettres ?
    Dans ce cas, 26 listes, chacune à trier, puis à coller.

    Il faut s'adapter au mieux aux données : un exemple pourrait orienter.
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  17. #17
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour,

    Le texte est composé de caractères alphanumériques commençant toujours par une lettre.

    Donc 26 possibilités pour la première lettre.

    Ce que tu appelles "liste" c'est quel objet, un TList ?

    Peut-il contenir plusieurs millions de lignes car le TStringList, sans trier et sans gérer les doublons, il plante à presque 6 millions de lignes ?

    Merci,
    ZiP

  18. #18
    Membre extrêmement actif Avatar de Jon Shannow
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    avril 2011
    Messages
    3 811
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : avril 2011
    Messages : 3 811
    Points : 7 409
    Points
    7 409
    Par défaut
    Y a combien de lignes au juste ?

    Je serais toi, je commencerais par essayer de charger dans une TStringList sans trier, juste pour voir si c'est possible ou pas et connaitre le nombre de lignes.
    Mais déjà tu sauras si c'est possible ou pas.

    Ensuite, tu charges dans 26 TStringList en fonction de la 1ere lettre, comme l'a suggéré tourlourou (au passage, brillante idée ), puis tu recolles les morceaux triés.

    Si ça ne marche pas, l'autre alternative est de charger le fichier dans une base (SQLite) par exemple et de faire un sort. Ça risque d'être long, mais ça devrait fonctionner, je pense.

    Bon courage.

    JS
    Au nom du pèze, du fisc et du St Estephe
    Au nom du fric, on baisse son froc...

  19. #19
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour Jon Shannow,

    J'ai actuellement 18 millions de lignes environs.

    J'ai déjà essayé avec un TStringList, sans trier et sans gérer les doublons, le programme fonctionne jusqu'à presque 6 millions de lignes et après, il plante

    Au vu de la quantité de données à trier et dédoublonner, je pense que je vais me tourner vers une base de données. Je connais plus MySQL que SQLite. Merci pour l'idée !

    Je considère donc ma question résolue.

    Merci,
    ZiP

  20. #20
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    3 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 3 631
    Points : 10 406
    Points
    10 406
    Billets dans le blog
    6
    Par défaut
    L'idée de séparer selon la première lettre n'avait d'intérêt que pour une distribution homogène.
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 24/12/2013, 15h13
  2. Trier les lignes d'un fichier texte
    Par supcomingenieur dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 23/04/2013, 01h38
  3. Boucle qui parcourt tout les ligne d'un fichier text
    Par accro-macro dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 10/05/2007, 21h21
  4. Réponses: 2
    Dernier message: 19/09/2006, 22h34
  5. Réponses: 3
    Dernier message: 26/04/2004, 13h51

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