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 :

[Delphi 7] Lire un gros fichier


Sujet :

Delphi

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 9
    Points : 7
    Points
    7
    Par défaut [Delphi 7] Lire un gros fichier
    Bonjour,

    Je fais un logiciel pour traiter des fichiers qui peuvent être lourds (2-4 mo), en ce moment, mon fichier fait 177ko et c'est déjà la catastrophe. Le fichier est chargé et traité (les lignes qui comment par un # ou un espace sont ignorées) et mise dans un listbox. Sur un fichier de 177ko (5673 lignes), le chargement prend environ 2 secondes. C'est acceptable je trouve. Le problème, c'est qu'il y a aussi la possibilité de fusionner deux fichiers, dès lors, le logiciel cherche s'il y a des doublons, si oui, il n'ajoute pas la ligne concernée dans le listbox. Pour 5673 lignes, ça prend 11 secondes ! Il y a donc deux problèmes :

    -La recherche de doublons est très lente
    -Le chargement finit par planter pour les trop gros fichiers

    J'ai entendu parler des Streams qui pourraient régler mes problèmes, mais je ne comprends pas le fonctionnement de celui-ci. Pourriez-vous m'aider ?

    Merci d'avance,
    bibi26

    Le code pour rechercher un doublon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     AssignFile(P,extractFilePath(application.exename)+'hosts');
     Reset(P);
     while not EOF(P) do
     begin
      ReadLn(P, ResultT);
      if (leftstr(ResultT, 1) <> '#') and (leftstr(ResultT, 1) <> ' ') then
      if (HostsC.IndexOf(ResultT) = -1) then
      begin
       New := StringReplace(ResultT, #9, ' ',[rfReplaceAll, rfIgnoreCase]);
       Hosts.Items.Add(New);
       HostsC.Add(ResultT);
      end;
     end;
     CloseFile(P);

  2. #2
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 925
    Points : 6 040
    Points
    6 040
    Par défaut
    Il y a plusieurs solutions à ton problème, mais il faudrait en dire plus sur le devenir du contenu de la listbox...(réutilisation ou autre)

    En attendant, tu peux essayer avec un TStringList et "jouer" sur la propriété Duplicate à dupError (ou qq chose comme ça ) qui fait monter une exception en cas de doublon.

  3. #3
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    +1 qi130

    Le TStringList est bien optimisé pour le chargement de fichier.
    Charger un fichier de 5 Mo ne pose strictement aucun problème et chargement en moins de 2 sec

    Le traitement derriere est aussi aisée.

    ListBox est visuel. Est-ce obligatoire pour ton traitement ?

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    Bonjour,

    Le TStringList est bien optimisé pour le chargement de fichier.
    J'utilise déjà le TStringList qui est effectivement rapide. HostsC est la TStringList et Hosts est la TListBox.

    Il y a plusieurs solutions à ton problème, mais il faudrait en dire plus sur le devenir du contenu de la listbox...(réutilisation ou autre)
    La TStringList charge le fichier, il fait les traitements et son contenu est copié dans la TListBox. Ma manière de procéder doit être mauvaise :

    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
     Hosts.Clear;
     HostsC := TStringList.Create;
     HostsC.LoadFromFile(Chemin);
     H := 0;
     F := HostsC.Count;
     if (not(F = 0)) then
     repeat
      if (leftstr(HostsC.Strings[H], 1) <> '#') and (leftstr(HostsC.Strings[H], 1) <> '') then Hosts.Items.Add(HostsC.Strings[H]);
      Inc(H);
     until (H >= F);
     H := 0;
     F2 := Hosts.Count;
     if (not(F = 0)) then
     repeat
      Hosts.ItemIndex := 0;
      New := StringReplace(Hosts.Items.Strings[Hosts.ItemIndex], #9, ' ',[rfReplaceAll, rfIgnoreCase]);
      Hosts.DeleteSelected;
      Hosts.Items.Add(New);
      Inc(H);
     until (H >= F2);
    Le problème est que dans le fichier en question (fichier hosts), c'est une tabulation qui sépare l'adresse locale de l'adresse du site, la TListBox ne l'accepte pas et l'adresse locale est collé à l'adresse du site. C'est pour ça que la TStringList effectue quelques modifications avant de l'entrer dans la TListBox.

    ListBox est visuel. Est-ce obligatoire pour ton traitement ?
    Il n'est pas obligatoire pour le traitement, mais il est doit être visuel pour que la personne puisse y faire des modifications s'il le souhaite.

  5. #5
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 925
    Points : 6 040
    Points
    6 040
    Par défaut
    Déjà 1 remarque sur ce type de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    H := 0;
     F := HostsC.Count;
     if (not(F = 0)) then
     repeat
      if (leftstr(HostsC.Strings[H], 1) <> '#') and (leftstr(HostsC.Strings[H], 1) <> '') then Hosts.Items.Add(HostsC.Strings[H]);
      Inc(H);
     until (H >= F);
    Il est toujours aventureux de gérer les indices de boucle quand on peut s'en passer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    For h:=0 to HostsC.Count-1 do
       if etc...
    Ensuite, pourquoi ne pas traiter avant l'insertion dans Hosts ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    For h:=0 to HostsC.Count-1 do
       if (leftstr(HostsC.Strings[H], 1) <> '#') and (leftstr(HostsC.Strings[H], 1) <> '') then begin
          New := StringReplace(HostCs.Strings[H], #9, ' ',[rfReplaceAll, rfIgnoreCase]);
          Hosts.Items.Add(New);
       end;

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    Incroyable, le chargement du fichier de 177ko prend 0,1s. Merci beaucoup pour ce conseil. Je m'en vais voir pour la fonction Duplicate.

    EDIT : Ça fonctionne et c'est franchement rapide

    Encore merci !

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

Discussions similaires

  1. Lire un gros fichier UnicodeString
    Par devroot dans le forum C++Builder
    Réponses: 1
    Dernier message: 22/01/2009, 13h47
  2. Lire de gros fichiers de logs
    Par johnnyjohnny dans le forum Général Python
    Réponses: 15
    Dernier message: 18/06/2008, 10h38
  3. Lire des gros fichiers
    Par alain123 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 04/09/2007, 09h16
  4. [XML]lire un gros fichier de format xml et l'envoyer
    Par diamonds dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 17/10/2006, 15h33
  5. Peut-on lire des gros fichiers(100k) avec "TClientSocke
    Par Fred LEM dans le forum C++Builder
    Réponses: 3
    Dernier message: 20/12/2004, 14h41

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