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

Langage Delphi Discussion :

Manipuler un gros fichier texte


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 144
    Points : 47
    Points
    47
    Par défaut Manipuler un gros fichier texte
    Bonjour,

    Je recherche un moyen optimiser pour insérer dans un fichier texte assez gros des bloc de texte.

    Ce bloc de texte peut être insérer plusieurs fois dans le fichier de destination.

    En effet il doit s'insérer suit à une recherche d'une chaîne de caractère.

    Exemple fichier à modifier :
    dddd
    fr
    ffgt
    ght


    Je désire insérer en fr et ffgt un bloc de texte :
    rrr
    tyuuy
    rrrr

    Résultat désiré :

    dddd
    fr
    rrr
    tyuuy
    rrrr
    ffgt
    ght

    Donc ma première idée est de ligne le fichier de source ligne par ligne, le recopier ligne par ligne et dès que la ligne est égal à fr, j'ajoute mon bloc de ligne.

    Merci pour votre aide et idées.

    Laurent

  2. #2
    Membre chevronné Avatar de philnext
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 552
    Points : 1 780
    Points
    1 780
    Par défaut
    Ben ton idée est pas mal...
    Ou sinon tu peux passer ton fichier dans une TStringList et manipuler celle ci, c'est plus facile mais limité pour la taille des fichiers.

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Autre suggestion : Si la mem-vive-disponible est insuffisante pour charger la totalité du gros fichier dans une StringList il reste la possibilité d'utiliser les Stream :

    1 ) - Lire le FileStream-Source jusqu'à la position du premier CRLF suivant la chaîne de caractère "fr".
    2) - Copier, depuis cette position jusquà la fin de ce FileStream, la deuxième partie de ce FileStream vers un FileStream-de-mémorisation-temporaire,
    3) - Ajouter le bloc de lignes à insérer dans le FileStream-Source à la suite du CRLF cité en 1)
    4) - Ajouter le FileStream-de-mémorisation-temporaire à la fin du FileStream-Source.
    5) - Effacer du disque le FileStream-de-mémorisation-temporaire.

    Par contre si la mem-vive-disponible est suffisante pour charger la totalité du "gros" fichier dans une StringList l'utilisation d'une StringList rend les choses beaucoup plus simples:
    - chargement du fichier-source avec LoadFromFile,
    - recherche d'une chaîne de caractère entière avec IndexOf, ou recherche d'une sous-chaine avec Pos(),
    - insertions avec Insert,
    - écrasement du fichier-source avec SaveToFile.

    A+

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 144
    Points : 47
    Points
    47
    Par défaut
    Merci pour ces propositions.

    Si la mémoire vive devenait pleine, vais-je obtenir un message d'erreur type out of memory et ainsi prévenir l'utilisateur.

  5. #5
    Membre chevronné Avatar de philnext
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 552
    Points : 1 780
    Points
    1 780
    Par défaut
    Disons que si tu veux charger en mémoire il est plutôt recommandé de vérifier la taille de ton fichier et de la mémoire dispo. avant

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

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Etudie ce sujet , si j'ai le temps, je dois finir la classe TTextFileReader pour y inclure l'insertion ... aussi ce sujet

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 144
    Points : 47
    Points
    47
    Par défaut
    Merci, j'avais effectivement lu ce post hier soir.

    A voir effectivement ta classe TTextFileReader .

    A bientôt,

    Laurent

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

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Sinon, le plus efficace, est de recopier le fichier ligne à ligne via un ReadLn (ou Stream comme le propose Gilbert Geyer ou comme dans ma classe TTextFileReader, le fichier d'index généré par celle-ci pourrait te servir pour manipuler le fichier plus rapidement en binaire par la suite), et quand tu arrive à la ligne choisie, tu insères tes nouvelles, puis tu termine la recopie, c'est le problème du fichier texte, la manipulation est lourde ... car il n'est pas fait pour le grand volume ...

    Sinon, la TStringList, si la mémoire vive est suffisante, pas évident de la prévoir (sans lire le fichier), c'est la taille du fichier + 16o x nombreDeLigne + quelques miettes ... sachant qu'il faut laisser en plus au moins la taille du fichier entier pour les mémoires tampons, dès que cela dépasse un certain taux de la mémoire vive, cela swappe et là les performances chutent (presque 100 fois plus lent qu'une lecture direct même répété ... car bcp d'aller retour DD-RAM, il me semble que les Erreurs de Pagination indique le nombre de va et vient ...)

  9. #9
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-Bonjour,

    Voiçi de quoi tester la mem-vive-disponible pour voir si on peut charger le "gros" fichier dans une StringList :
    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 memDispo : DWORD; // renvoie mem vive dispo
      var      Mem : TMemoryStatus;
      begin    Mem.dwLength:=SizeOf(TMemoryStatus); GlobalMemoryStatus(Mem);
               memDispo:=Mem.dwAvailPhys;
      end; // Pour plus de détails voir 'MemoryStatus' dans l''aide SDKWindows
     
    function fGoMoKo(const mem : DWord) : string; // pour afficher une taille en DWord via la string-Result au format raccourci
      var      e : byte; s : string; r : Extended;
      begin    e:=0; r:=mem;
               if r>=0 then
               begin while r>1024 do begin r:=r/1024; inc(e); end;
                     case e of
                        0 : s:='Oct';
                        1 : s:='Ko';
                        2 : s:='Mo';
                        3 : s:='Go';
                        4 : s:='To';
                     end;
                     fGoMoKo:=FormatFloat('#.###',r)+' '+s;
               end;
      end; // fGoMoKo
    A+

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 144
    Points : 47
    Points
    47
    Par défaut
    Merci

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 144
    Points : 47
    Points
    47
    Par défaut
    Petite question, avec une boucle While not eof et un readln comment puis-je faire un saut de 5 ligne et continuer la lecture

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

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    tu ne peux pas te déplacer avec un seek, mais tu peux "simuler" ce comportement ! tu fois lire les 5 lignes ... c'est justement l'intéret de TTextFileReader qui te permet de te balader simplement ... mais je n'ai pas fait l'insertion (dès que je l'ai le temps, je me ferais un plaisir de le faire, un réel plaisir d'algo ... car il est indispensable que je reconstruise en plus l'index au passage, hum chic chic des romains ...)

    tu peux faire sinon ...

    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
    While not EOF(Fichier) do
    begin
      if CompteurSaute > 0 then  
      begin
        Dec(CompteurSaute);
        ReadLn(Fichier); // pas de variable chaine, cela économise mémoire, donc du temps
      end
      else
      begin
        ReadLn(Fichier, Chaine);
        if Analyser(Chaine) then
          Traiter(Chaine)
        else
          CompteurSaute := 5;
      end;  
    end;

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 144
    Points : 47
    Points
    47
    Par défaut
    Effectivement j'ai fait le même type de code pour l'instant et j'attends de tes nouvelles pour ta classe.

    bon courage

    Laurent

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 144
    Points : 47
    Points
    47
    Par défaut
    Est-il possible de connaitre le nombre de ligne rapidement d'un fichier texte sans le faire défiler entièrement.

    But : faire avancement un tscrollbar pendant mon traitement.

    Laurent

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

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Non, plus, soit tu fais une fonction qui compte les #13#10 avec un gros buffer, soit un ReadLn en boucle ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
          CountLn := 0;
          AssignFile(FLNC, FileName);
          Reset(FLNC);
          try
             while not Eof(FLNC) do
             begin
                Inc(CountLn);
                Readln(FLNC);
             end;
          finally
             CloseFile(FLNC);
          end;
    ou via ma fonction SearchStringInFile, c'est normalement plus rapide que ReadLn ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var
       OffSets: TIntegerDynArray;
    begin
      CountLn := SearchStringInFile(EdPathSearch.Text, #13#10, OffSets, False);

Discussions similaires

  1. Réponses: 50
    Dernier message: 19/10/2007, 23h38
  2. JTextPane : Affichage de gros fichiers texte
    Par patanoc dans le forum AWT/Swing
    Réponses: 13
    Dernier message: 26/02/2007, 19h10
  3. [BATCH] Manipulation dans un fichier texte
    Par Bloodscalp dans le forum Windows
    Réponses: 2
    Dernier message: 13/09/2006, 15h49
  4. [C#]Lecture gros fichier texte
    Par kekesilo dans le forum Windows Forms
    Réponses: 5
    Dernier message: 20/05/2006, 13h58
  5. [VBA-E]Telecharger un gros fichier texte
    Par Elstak dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 10/04/2006, 09h16

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