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 :

[D2009] TFileStream Big Files (demande de conseil)


Sujet :

Delphi

  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut [D2009] TFileStream Big Files (demande de conseil)
    Bonjour à toutes et à tous,

    Je viens vers vous pour un conseil.

    Je réalise un outils de traitement de fichier pour passer d'un format connu, vers un autre format connu "connu = c'est moi qui le connais lolol"

    Voici la structure du fichier source (pas de séparateur) :
    Colonne :
    Numéro Longueur Position Descriptif Type
    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
    Numéro  Longueur  Position  Descriptif Type 
    1  8  1  Pièce  AlphaNum 
    2 9 9 Compte comptable **  AlphaNum 
    3 6 18  Date écriture  JJMMAA 
    4 60 24 Libellé manuel  AlphaNum 
    5 20 84 Débit * Numérique 
    6 20 104 Crédit * Numérique 
    7 260 124 Répartition  échéance (10 échéances maxi)
      6    Date échéance 1  JJMMAA 
      20   Montant 1 *  Numérique 
      ...... ...... ......       
      6   Date échéance10  JJMMAA 
      20   Montant 10 *  Numérique 
    8 400 384 Répartition analytique (10 poste ana maxi)  
      20    Poste analytique 1 ***  AlphaNum 
      20   Montant 1 *  Numérique 
      ...... ...... ......       
      20   Poste analytique 10 ***  AlphaNum 
      20   Montant 10 *  Numérique 
    9 8 784 Devise AlphaNum 
    10 20 792 Cours Numérique 
    11 60  812 Libellé Pièce  AlphaNum 
    12 1 872 Flag Pièce ****  Numérique 
    13 15 873 Quantité  Numérique 
    14 3 888 Unité AlphaNum 
    15 30 891 Réserve    
    16 2  921 Fin de partie ECR (0d0a) pour ECR, vide pour ECR2 
    17 60 923 Nom du logiciel émetteur AlphaNum 
    18 60 983 Code du dossier émetteur AlphaNum 
    19 60 1043 Type de la pièce AlphaNum 
    20 30 1103 Code document de la pièce défini par le transfert (Identifiant DGI : IdentDGI) Numérique 
    21 120 1133 Info libre (inclut Date de création de la pièce, Utilisateur ayant créé la pièce)   
    22 2 1253 Fin de partie ECR2 (0d0a)
    Pour le moment peut importe la transformation, dans mon premier travail je doit parcourir ce fichier et récolter tout les comptes "sans doublon" position 9 longueur 9 et les mettre dans une colonne de StringGrid.

    Bref, j'ai lu différent article sur les TFileStream en effet mon fichier de départ peut être énorme, mais j'ai rien compris... lol j'ai lu cet article http://sjames.developpez.com/BigFiles/ et télécharger la source mais je vois aucune recherche texte là dedans, il parle d'octets !!

    Mes questions :
    - Puis-je faire des recherches texte en utilisant les TFileStream ? (avez-vous un lien avec un exemple ?)
    - Qu'elle serais pour vous l'utilité de créer un Record en inscrivant cette structure et de l'utiliser par la suite pour la lecture ?

    J'ai déjà créé le programme qu'il lit tout cela mais face à un fichier de plus de 200 MO cela mais 8 heures !!!

    Tout autre idée est la bien venue. Sachant que peut-être sous D2009 il existent des trucs de ouf

    J'ai également lu cet article de shaiLeTroll : http://www.developpez.net/forums/m2419880-8/

  2. #2
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    J'avous ne pas comprendre la structure du fichier, pas de description des types ou de leurs déclarations ...
    tu en es l'auteur ?

    quand on decrit une structure de fichier le mieux est de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    recapitulatif : [nom(taille), nom(taille)...]
    description :
    nom champs [taille en byte] type / type compatible
    nom champs [taille en byte] type / type compatible
    ...
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    [StrSize(2), StrVar(0..StrSize), Rect(4*4), Pixel(4=R,G,B,A(4*1))]
     
    StrSize [2] Word / Unsigned Int 16bits
    StrVar [0..StrSize] string / Ansi Char 8bits
    Rect [4*4] TRect / Integer * 4 
    Pixel [4=
              R, G, B, A [4*1] byte/ unsigned int 8
           ] TColor / Int 32bits
    on peu facilement retranscrire cette structure par la suite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    type
      TMaStructure = record
        StrSize : word;
        StrVar  : string;
        Rect    : TRect;
        case integer of
          0: (Pixel : integer);
          1: (R,G,B,A : byte);
      end;

    pour la structure que tu nous donne ... j'avous ne pas trop savoir comment la retranscrire.

    numero : inutile ...
    longueur : necessaire mais doit être précisé 4 <> 0..4 par exemple
    nom : utile pour ecrire le nom d'un champ
    description : facultative
    type : necessaire mais doit être précisé, AlphaNum ? JJMMAA ?


    sinon comme dis montor, une BDD serait plus performante pour ce genre de chose.
    SQLite est pas mal, simple, facilement deployabe (DLL), syntaxe proche de MySQL, fichier compatible avec d'autres SGBD (MySQL par exemple pour les fichiers .sql)
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  3. #3
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Salut,

    Alors pour mieux expliqué :
    La structure ici présenté est en fait 1 ligne du fichier text, chaque ligne est donc de taille 1253 et se décompose comme expliqué.

    Alors vous pensez que d'envoyé chaque ligne dans un base de donnée et ensuite faire des traitements SQL c'est le plus rapide ?

  4. #4
    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,

    Puisque tu connais la position et la taille des fragments du texte de 200 MO que tu veux récupérer tu peux déjà extraire ces fragment dans un MemoryStream alimenté à partir d'un TFileStream avec :

    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
    function CopyFragFile(const FileName : String; From,SizeFrag : longint) : tMemoryStream;
    //       Renvoie un tMemoryStream contenant la copie d'un fragment d'un fichier à
    //       partir de la position From et de taille SizeFrag en octets octets.
    //       Utilisable si SizeFrag ne dépasse pas la mem-vive-disponible et si la
    //       la taille du fichier-source est inférieure à 2 Go.
    var      FS : tFileStream;
    begin    Result:=tMemoryStream.create;
             if (not FileExists(FileName)) then
             begin Showmessage('Fichier '+FileName+' : inexistant'); EXIT; end;
             FS := TFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
             FS.Position := From;
             Result.CopyFrom(FS, SizeFrag);
             Result.Position:=0;
             FS.Free;
    end;
    Concernant la suite, tu dis :
    ... récolter tout les comptes "sans doublon"
    ...
    Puis-je faire des recherches texte en utilisant les TFileStream ?
    Si t'as besoin des recherches de texte uniquement pour supprimer les doublons il sera possible d'utiliser CopyFragFile et d'envoyer chaque fragment (auquel on ajoute #13#10 comme séparateur) dans un TFIlestream de destination pour en créer un autre fichier de taille forcément plus faible et dans lequel on supprimera les doublons (il y a un code très rapide sur ce site pour la supression des doublons).

    A+.

    EDIT : Voir ici le code pour la supression des doublons : http://www.developpez.net/forums/d44...t/#post2784174

    Exemple : Pour la supression dans un fichier de tests de 200000 lignes dont une ligne sur deux est du texte aléatoire de 62 caractères suivis du numéro de ligne et une ligne sur deux est égale à la chaîne '<<< MI-DOUBLON >>>' (8540 Ko) avec la procedure SupprDoublonsAOS : 1599 ms (Pentium III à 1,13 GHz).
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 091
    Points : 41 069
    Points
    41 069
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par BuzzLeclaire Voir le message
    Salut,

    Alors vous pensez que d'envoyer chaque ligne dans une base de données et ensuite faire des traitements SQL c'est le plus rapide ?
    salut,

    pas forcement , une tstringlist contenant ces fameux comptes ça pourrait faire l'affaire ?
    avec un petit Indexof(compte) pour tester l'ajout ou non
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bonjour,

    Gilbert Geyer : Au niveau des Stream je ne connaissais que la compression zip, ce qui fait que je ne sait pas comment utiliser ta proposition CopyFragFile. Je viens d'essayer mais je ne sais pas lire TMemorystream pour voir chaqu'une de mes lignes.
    voici un petit exemple du fichier que je lis (ici il y a juste 8 lignes) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    F10     411000000120309Facture F10 ARTI-BAT                                        00000000000000098.78                    30040900000000000000098.7812031000000000000000031.51                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                E       6,55957             Facture F10 ARTI-BAT                                        1                                                  Logiciel XXX                                                LOGICI                                                      FC                                                          5                             120309 00;ADMIN                                                                                                         
    F10     419100000120309Facture F10 ARTI-BAT                                        00000000000000500.00                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        E       6,55957             Facture F10 ARTI-BAT                                        0                                                  Logiciel XXX                                                LOGICI                                                      FC                                                          5                             120309 00;ADMIN                                                                                                         
    F10     411700000120309Facture F10 ARTI-BAT                                        00000000000000031.51                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        E       6,55957             Facture F10 ARTI-BAT                                        0                                                  Logiciel XXX                                                LOGICI                                                      FC                                                          5                             120309 00;ADMIN                                                                                                         
    F10     707019000120309Facture F10 ARTI-BAT                                                            00000000000000339.58                                                                                                                                                                                                                                                                    CH007               00000000000000339.58                                                                                                                                                                                                                                                                                                                                                                        E       6,55957             Facture F10 ARTI-BAT                                        0                                                  Logiciel XXX                                                LOGICI                                                      FC                                                          5                             120309 00;ADMIN                                                                                                         
    F10     706000001120309Facture F10 ARTI-BAT                                                            00000000000000187.42                                                                                                                                                                                                                                                                    CH007               00000000000000187.42                                                                                                                                                                                                                                                                                                                                                                        E       6,55957             Facture F10 ARTI-BAT                                        0                                                  Logiciel XXX                                                LOGICI                                                      FC                                                          5                             120309 00;ADMIN                                                                                                         
    F10     4457DC001120309Facture F10 ARTI-BAT                                                            00000000000000016.19                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    E       6,55957             Facture F10 ARTI-BAT                                        0                                                  Logiciel XXX                                                LOGICI                                                      FC                                                          5                             120309 00;ADMIN                                                                                                         
    F10     445800001120309Facture F10 ARTI-BAT                                                            00000000000000005.16                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    E       6,55957             Facture F10 ARTI-BAT                                        0                                                  Logiciel XXX                                                LOGICI                                                      FC                                                          5                             120309 00;ADMIN                                                                                                         
    F10     445800001120309Facture F10 ARTI-BAT                                                            00000000000000081.94                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    E       6,55957             Facture F10 ARTI-BAT                                        0                                                  Logiciel XXX                                                LOGICI
    Comment avec ta procédure je parcours chaque ligne ? et comment je récupérer toutes les données position 9 longueur 9 de chaque ligne ?
    Je suis désolé mais je comprends bien ces procédés.

    Sergio Master : Salut serge comment vas-tu ?. Merci pour ta proposition mais dans cette éventualité je devrais faire une lecture ligne à ligne de mon fichier pour construire mon TStringlist, mais pourquoi pas. J'attends de comprendre (avec mon peut de cervelle qui me reste) les histoires de Stream.

    Merci à vous.

  7. #7
    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,

    Voici un exemple d'utilisation où je récupère le MemoryStream issu de CopyFragFile pour alimenter un RichEdit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TForm1.SpeedButton2Click(Sender: TObject);
    var       MS : TMemoryStream; FileName : String; From,SizeFrag : longint;
    begin
              FileName:=ExtractFilePath(Application.ExeName)+'test0.mem'; // <- nom du fichier-source.
              From:=856; SizeFrag:=7039;
              MS:=CopyFragFile(FileName,From,SizeFrag);
              RichEdit1.Lines.LoadFromStream(MS)
              MS.Free;
    end;
    Comment avec ta procédure je parcours chaque ligne ? et comment je récupérer toutes les données position 9 longueur 9 de chaque ligne ?
    ... si dans l'exemple de code ci-dessus tu écris From:=9; et SizeFrag:=9 cela t'affichera dans le RichEdit les données commençant à la position 9 et de longueur 9 de la première ligne du fichier-source.
    Fais un test pour vérifier s'il faut From:=9 ou From:=8 car les positions dans les Stream commencent par 0.
    Bien entendu le RichEdit ne sert ici que pour visualiser le bon calage initial.
    Ensuite, au lieu d'utiliser un RichEdit tu peux récupérer le contenu du MemoryStream MS avec MS.read(PChar(S)^,SizeFrag); comme le suggère Montor mais au-lieu de faire LisStrings.Text:=S; il vaut mieux faire LisStrings.Add(S); (avec var S : string; LisString : tStringList) car je suppose que tu veux extraire également traiter les autres lignes et les ajouter à la StringList.

    Pour récupérer les autres lignes il faudra une boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
           ...  
           From:=8 ou 9; SizeFrag:=9; 
           for i:=1 to 10 do
           begin MS:=CopyFragFile(FileName,From,SizeFrag);
                   MS.read(PChar(S)^,SizeFrag);   
                   LisStrings.Add(S); 
                   inc(From,Pas); 
                   MS.Free;
           end;
           LisString.SaveToFile(nomDuFichierDeDestination);
    ... dans inc(From,Pas); il suffit de remplacer 'Pas' par la longueur de la string-source que t'as donnée en exmple :
    F10 411000000120309Facture F10 ARTI-BAT
    puisque toutes tes lignes-sources ont la même taille.

    Au fait tu disais :
    chaque ligne est donc de taille 1253
    ... on dirait que tes lignes ont rétréci au lavage depuis hier.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  8. #8
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message

    Au fait tu disais :
    ... on dirait que tes lignes ont rétréci au lavage depuis hier.

    A+.
    c'était pour l'exemple... lol

    Je viens de palnter mon delphi 2009 avant de lire ton topic avec cela
    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
    unit Unit1;
     
    interface
     
    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;
     
      type TData = record
        NumFact         : AnsiString;
        NumCompte       : AnsiString;
        DateEcr         : AnsiString;
        libelleEcr      : AnsiString;
        NumPiece        : AnsiString;
        MontantDebit    : AnsiString;
        MontantCredit   : AnsiString;
      end;
     
      TDonnees = array of TData;
     
      type
      TForm1 = class(TForm)
      Btnlire: TButton;
      ListBox1: TListBox;
      procedure BtnlireClick(Sender: TObject);
      private
        { Déclarations privées }
      public
      { Déclarations publiques }
      procedure MontrerDonnees (Donnees: TDonnees);
    end;
     
    var Form1: TForm1;
     
    implementation
    {$R *.dfm}
     
    procedure TForm1.BtnlireClick(Sender: TObject);
    var
      Donnees: TDonnees;
      Stream: TStream;
      I: integer;
      Len: Longint;
    begin
      Stream := TFileStream.Create('c:\essai\' + 'essai.txt', fmOpenRead);
      try
        Stream.Read(Len, sizeof(Len));
    //    showmessage(inttostr(sizeof(len)));
        SetLength(Donnees, 8);
        for i := 0 to Len - 1 do begin
          Stream.Read(Donnees[I].NumFact, SizeOf(Donnees[I].NumFact));
          Stream.Read(Len, SizeOf(Len));
        end;
      finally
        Stream.Free;
      end;
        MontrerDonnees(Donnees);
    end;
     
    procedure TForm1.MontrerDonnees (Donnees: TDonnees);
    var Len : longint;
      i : longint;
    begin
      // affichage des données lues, dans un listbox
      listbox1.Items.Clear;
      Len := length(Donnees);
      for i := 0 to Len - 1 do begin
        listbox1.items.Add(Donnees[i].NumFact);
      end;
    end;
    end.
    je sais c'est complétement nul, mais j'essai de comprendre...

    Je me plonge dans tes explications et j'essai.

    A oui il faut que les lignes comportent une seule fois le caractères #0 ? ou chaque morceau ? et si j'ai pas cela dans mon fichier ? ... enfin je vais voir...

    le délire ce truc...

  9. #9
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    alors voilà où j'en suit :

    Je pars de ce fichier , je l'ai retouché les lignes font toutes 123 en taille et il y a que 8 lignes

    Fichier Sources essai.txt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    FC000056411DEPTOU100207Fact FC000056 DEP TOUT                                                    358.80                0.00
    FC000056707000000100207Fact FC000056 DEP TOUT                                                      0.00              300.00
    FC000056445711000100207Fact FC000056 DEP TOUT                                                      0.00               58.80
    FC000051411AL6400190107Fact FC000051 ALARME                                                      734.20                0.00
    FC000051419100000190107Fact FC000051 ALARME                                                     1000.00                0.00
    FC000051708510000190107Fact FC000051 ALARME                                                        0.00              450.00
    FC000051707000000190107Fact FC000051 ALARME                                                        0.00             1000.00
    FC000051445711000190107Fact FC000051 ALARME                                                        0.00              284.20
    Si j'ouvre ce fichier je ne voit pas de caractère de fin, il y a un retour chariot, dois-je m'assurer de quelquechose dans ce fichier ?

    Voici le projet :
    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
    unit Unit1;
     
    interface
     
    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;
     
      type
      TForm1 = class(TForm)
      Btnlire: TButton;
      function CopyFragFile(const FileName : String; From,SizeFrag : longint) : tMemoryStream;
      procedure BtnlireClick(Sender: TObject);
      private
        { Déclarations privées }
      public
      { Déclarations publiques }
    end;
     
    var Form1: TForm1;
     
    implementation
    {$R *.dfm}
     
    function TForm1.CopyFragFile(const FileName : String; From,SizeFrag : longint) : tMemoryStream;
    //       Renvoie un tMemoryStream contenant la copie d'un fragment d'un fichier à
    //       partir de la position From et de taille SizeFrag en octets octets.
    //       Utilisable si SizeFrag ne dépasse pas la mem-vive-disponible et si la
    //       la taille du fichier-source est inférieure à 2 Go.
    var      FS : tFileStream;
    begin    Result:=tMemoryStream.create;
             if (not FileExists(FileName)) then
             begin Showmessage('Fichier '+FileName+' : inexistant'); EXIT; end;
             FS := TFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
             FS.Position := From;
             Result.CopyFrom(FS, SizeFrag);
             Result.Position:=0;
             FS.Free;
    end;
     
    procedure TForm1.BtnlireClick(Sender: TObject);
    Var
      i, pas: Integer;
      From, SizeFrag: Longint;
      s, FileName, nomDuFichierDeDestination: string;
      LisStrings: TStringlist;
      MS : TStream;
    begin
       LisStrings := TStringList.Create;
       Filename:= 'c:\essai\essai.txt';
       nomDuFichierDeDestination:= 'c:\essai\essaitransformer.txt';
       pas := 123;
       From:=8; SizeFrag:=9;
       for i:=1 to 10 do
       begin MS:=CopyFragFile(FileName,From,SizeFrag);
               MS.read(PChar(S)^,SizeFrag);
               LisStrings.Add(S);
               inc(From,Pas);
               MS.Free;
       end;
       LisStrings.SaveToFile(nomDuFichierDeDestination);
       LisStrings.Free;
    end;
     
    end.

    A l'utilisation cela bug total, il compile bien mais j'ai des erreurs EAccessViolation.

  10. #10
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bon je viens de voir un truc :
    Ma boucle for je l'ai changé comme cela

    cette fois le fichier destinaiton est bien créer sauf que
    1) il est vide
    2) si je ferme la fiche je retombe sur une erreur EAccessViolation.

  11. #11
    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,

    je sais c'est complétement nul, mais j'essai de comprendre...
    ... t'as raison : c'est en forgeant qu'on devient forgeron.

    Je me plonge dans tes explications et j'essai.
    ... je viens de tester l'histoire de la boucle et je me suis rendu compte d'un oubli dans le bout de code de toute à l'heure :

    il faut ajouter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetLength(S,MS.Size); juste devant MS.read(PChar(S)^,SizeFrag);
    ... sinon plantage.

    A oui il faut que les lignes comportent une seule fois le caractères #0 ? ou chaque morceau ?
    ... j'avais parlé d'ajouter un #13#10 uniquement pour le cas d'une accumulation des fragments dans un TFIlestream de destination, mais comme on ajoute le contenu de la string 'S' dans une StringList avec LisStrings.Add(S); les #13#10 seront présents automatiquement dans le fichier de destination.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  12. #12
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    il faut ajouter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetLength(S,MS.Size); juste devant MS.read(PChar(S)^,SizeFrag);
    ... sinon plantage.
    Je confirme... lol la sa plante plus mais le résultat est étonnant !!!
    voilà le resultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ?????????
    ?????????
    ?????????
    si si promis c'est que des ? je sais pas pourquoi, j'ai essayer 8 et 9 en From mais pareil...

  13. #13
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Ah

    J'ai trouvé, j'ai mis S en AnsiString au lieu de String et voilà le résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    411DEPTOU
    567070000
    005644571
    000051411
    FC0000514
     
    FC00005
    Bon c'est pas vraiment le resultat attrendu il y a un décalage au moment de la deuxieme ligne... je vais voir.

  14. #14
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    purée sa fonctionne...

    Merci enormément Gilbert, t'es un prince.

    Maintenant est-ce zue tu crois que c'est utilise d'utilisez un record ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      type TData = record
        NumFact         : AnsiString;
        NumCompte       : AnsiString;
        DateEcr         : AnsiString;
        libelleEcr      : AnsiString;
        NumPiece        : AnsiString;
        MontantDebit    : AnsiString;
        MontantCredit   : AnsiString;
      end;
     
      TDonnees = array of TData;
    Ou alors est-ce possible de mettre en paramétrage le debut + la longueur de chaque Champ afin d'éviter d'écrire manuellement From et Size ?

    je sais pas si je suis claire là ?

  15. #15
    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,

    Ok, je vois qu'on avance. Pour info j'ai également utilisé CopyFragFiles pour extraire une image dans un fichier qui regroupait plusieurs images de même taille : les Stream véhiculent n'importe quelles données.

    Bon c'est pas vraiment le resultat attrendu il y a un décalage au moment de la deuxieme ligne... je vais voir.
    ... ben, théoriquement il ne devrait pas y avoir de décalage si toutes les lignes sont de même taille et si le 411DEPTOU de la première ligne est bien calé sur la bonne position de départ.

    A+.
    .
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  16. #16
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Re-bonjour,

    Ok, je vois qu'on avance. Pour info j'ai également utilisé CopyFragFiles pour extraire une image dans un fichier qui regroupait plusieurs images de même taille : les Stream véhiculent n'importe quelles données.


    ... ben, théoriquement il ne devrait pas y avoir de décalage si toutes les lignes sont de même taille et si le 411DEPTOU de la première ligne est bien calé sur la bonne position de départ.

    A+.
    .
    Regarde mon dernier post...

  17. #17
    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,

    Maintenant est-ce zue tu crois que c'est utilise d'utilisez un record ?
    ....
    Ou alors est-ce possible de mettre en paramétrage le debut + la longueur de chaque Champ afin d'éviter d'écrire manuellement From et Size ?
    ... c'est vraiment pas clair du tout.
    ... que vient faire ici ce record : il concerne le fichier-source ou le fichier-destination ?
    ... et pour la deuxième question faudrait également un peu plus d'explications.

    A+.

    EDIT : posts croisés.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  18. #18
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message

    ... et pour la deuxième question faudrait également un peu plus d'explications.

    A+.

    EDIT : posts croisés.
    Alors voilà.
    Le format source ne chengeras jamais comme expliquer sur mon premier poste.

    Plutot que d'écrire à la main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    From:=9; Size:=9;Pas:=1253
    Est-il intéressant de mettre cela dans un Records ou un tableau prédéfinie ? je veux juste savoir si cela sera exploitable par la suite avec les Stream.

    Cela dans le but où je souhaite pas seulement récupérer la position 9 longueur 9, genre

    copyfragFiles(,,,[NumCompte]); où NumCompte serais préparamétré 9,9
    ou
    copyfragFiles(,,,[NumFactures]); où NumCompte serais préparamétré 1,8

    Ou alors récupérer les deux info copyfragFiles(,,,[NumFactures,NumCompte]);

    J'espere que cela est mieux expliqué.

  19. #19
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    j'ai peut etre une solution!

    en utilisant l'API windows et les mappingfile.

    en utilisant cette méthode on récupère un pointeur sur le debut du fichier.

    puisque les elements semble fixe (1253 octets), il suffit de diviser la taille du fichier par 1253 pour avoir le nombre d'elements.
    ensuite il nous suffit d'un tableau de pointeur sur structure definie et de faire pointer chaque pointeur tout les 1253.
    du moins ça c'est dans la theorie.

    ce qui donne un truc du genre :

    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
     
    type
      PFileStruc = ^TFileStruc;
      TFileStruc = record
        ...
      end;
     
    const
      SizeOfFileStruc = SizeOf(TFileStruc);
     
    type
      TFileStrucList = packed record
        datas : array[0..MAXPOINTERS] of PFileStruc;
        count : integer;
      end;
    // voir interface de TList pour la valeur de MAXPOINTERS

    ensuite le filemapping (voir PJ), petite unité utile.

    a utiliser comme suit :

    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
     
    var
      FV : TFileView;
      PFS : PFileStruc;
      Count : integer;
    begin
      FV := TFileView.Create('C:\monfichier.truc');
      try
        if FV.Loaded then
        begin
           PFS := FV.View; // on lit PFileStruc par PFileStruc
           Count := FV.FileSize div SizeOfFileStruc; // nombre d'elements
           // ... //
        end;
      finaly
        FV.Free;
      end;
    end;
    edit :

    TFileView ouvre le fichier en Lecture seule, à toi de modifier pour activer l'ecriture.

    on peut utiliser un TList pour lister les structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for N := 0 to count-1 do
      List.Add(pointer( integer(PV.View) + (SizeOfFileStruc*N) ));
    List contient maintenant tout les pointeurs sur chaque structure du fichier.

    il suffira de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      FS: TFileStruc;
    begin
      FS := PFileStruc(List.Items[n])^;
    end;
    pour lire l'une des structure.
    Fichiers attachés Fichiers attachés
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  20. #20
    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,

    Ah : ça devient plus clair.

    Est-il intéressant de mettre cela dans un Records ou un tableau prédéfinie ? je veux juste savoir si cela sera exploitable par la suite avec les Stream.
    dans CopyFragFile(const FileName : String; From,SizeFrag : longint) : TMemoryStream
    le From et le SizeFrag peuvent provenir de n'importe où : Record ou Array of [1..n] OF Longint.

    Ou alors récupérer les deux info copyfragFiles(,,,[NumFactures,NumCompte]);
    ... ça c'est pas possible.
    ... pour obtenir ce résultat il faut d'abord récupérer la zone de NumFactures qui va dans la string 'S' de MS.read(PChar(S)^,SizeFrag); la mémoriser dans une string 'SCumul' puis récupérer dans 'S' la zone de NumCompte et faire SCumul:=SCumul + S et d'ajouter à la StringList où les deux champs seront présents sur une même ligne.

    A+.

    PS : comme je suis scotché à mon micro depuis ce mat, j'éteins mon micro et je vais rattraper mon repas de midi.

    EDIT : posts croisés, à demain.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

Discussions similaires

  1. Demande de conseil pour migration de lignes vers colonnes
    Par ririd dans le forum Administration
    Réponses: 6
    Dernier message: 04/11/2004, 17h02
  2. [Struts_Tiles VS CSS] Demande de Conseils
    Par sylvain_neus dans le forum Struts 1
    Réponses: 4
    Dernier message: 16/04/2004, 10h12
  3. [sqlbaseserver]demande de conseils/aides pour requêtes
    Par GéniuS77 dans le forum Langage SQL
    Réponses: 14
    Dernier message: 18/03/2004, 17h27
  4. demande de conseil
    Par stephane eyskens dans le forum EDI/Outils
    Réponses: 2
    Dernier message: 25/09/2003, 14h18

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