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 :

FileStream erreur de saisie


Sujet :

Delphi

  1. #1
    Membre du Club
    Homme Profil pro
    Animateur commercial
    Inscrit en
    Août 2011
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Animateur commercial

    Informations forums :
    Inscription : Août 2011
    Messages : 47
    Points : 41
    Points
    41
    Par défaut FileStream erreur de saisie
    Bonjour

    J'ai un petit souci en utilisant les FileStream. C'est la première fois. J'ai un fichier dans lequel j'ai une multitude de fichier. Les 4 premiers bytes décrivent le nombre de fichier. Après j'ai une structure sur 136 bytes qui se décompossent de la façon suivante :

    128 bytes -> Nom du fichier
    4 bytes -> Position du fichier dans le global
    4 bytes -> Pour la taille du fichier

    Je veux réecrire ce fichier. Je n'ai pas de souci pour la copie du nomde fichier, la taille. Et la copie du fichier. Mon problème vient de la position dans le fichier.
    J'ai mis une vérification de la position avec un showmessage pour savoir si l'emplacement que je voulais écrire était bon. Ma variable est correcte pour toutes les boucles par contre l'écriture de cette variable n'est pas bonne sauf pour la première boucle :-/

    Ci joint 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
     
    procedure TForm1.Button3Click(Sender: TObject);
    var
      Stream1,Stream2                           : TStream;
      NbFichier                                 : longint;
      i, i2,i3, FileSize, FilePos, Taille       : integer;
      filepath                                  : array[0..127] of AnsiChar;
      chemin                                    : string;
      Vide                                      : AnsiChar;
     
    begin
      NbFichier := Stringgrid1.RowCount-1;
     
      Stream1:=TFileStream.Create(Edit1.Text,fmOpenRead);
     
      try
      Stream2:=TFileStream.Create('d:\2.wad',fmOpenWrite or FMCreate);
      Stream2.Position :=0;
      Stream2.Write(NbFichier,4);
      for I := 1 to NbFichier do
      begin
        Stream2.Position := 4 + ((i-1)*136);
        Chemin := StringGrid1.Cells[1,i]+StringGrid1.Cells[0,i];
        for i2:= 1 to length(filepath) do
        begin
          if i2 <= length(chemin) then filepath[i2-1] := AnsiChar(Chemin[i2])
          else filepath[i2-1] := #0
        end;
        FileSize := StrToInt(StringGrid1.Cells[2,i]);
        FilePos := StrToInt(StringGrid1.Cells[3,i]);
        Stream2.Write(FilePath,Length(FilePath));
        Stream2.Write(Vide,4);
        Stream2.Write(FileSize,4);
     
      end;
      for I3 := 1 to NbFichier do
      begin
        Taille := 0;
        FileSize := StrToInt(StringGrid1.Cells[2,i3]);
        FilePos := StrToInt(StringGrid1.Cells[3,i3]);
        Stream2.Position := Stream2.Size;
        Stream1.Position:=FilePos;
        Stream2.CopyFrom(Stream1,FileSize);
        if i3 < NbFichier then
        begin
          vide := #0;
          Stream2.Write(vide,1);
        end;
        Stream2.Position := 4 + ((i3)*128);
        Taille := Stream2.Size - FileSize -1;
        Showmessage (IntToStr(Taille)); <-- La variable Taille renvoie la bonne donnée.
        Stream2.Write(Taille,4); <-- Ecrit la bonne variable taille pour la première boucle mais pas les suivantes :(
     
      end;
      finally
      Stream2.Destroy;
      Stream1.Destroy;
      end;
    end;

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 469
    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 469
    Points : 24 905
    Points
    24 905
    Par défaut
    Faudra revoir tout ça et simplifié avec AnsiString car il y a des manipulations de chaine peu optimisé et pouvant se remplacer par du StrLCopy ou StrPLCopy
    Pour les buffers non remplis au maximum bourrés de zéro cela se fait via ZeroMemory puis StrPLCopy

    Vide n'est pas alloué dans la première section, sa valeur peut être aléatoire, c'est un risque d'avoir soit n'importe quoi dans le fichier soit une VA

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream2.Position := Stream2.Size;
    C'est étrange cette opération, modifier la position comme ça,
    Si l'écriture du fichier est linéaire, au fur et à mesure, cela s'ajoute, donc cela n'est pas utile

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream2.Position := 4 + ((i3)*128);
    Avec ceci, on peut penser que l'écriture est donc non linéaire, cela se déplace dans le fichier, je pense que ce calcul est faux si en réalité les modifications de positions ne sont pas inutiles en repensant l'algo

    attention à l'imbrication des try finally, si le constructeur de Stream2 échoue, la référence aura une valeur probablement aléatoire et c'est une VA garanti sur le Destroy dans le finally
    D'ailleurs Destroy ... personne ne lit l'aide et suit les conseils ?
    System.TObject.Destroy
    N'appelez pas directement Destroy. Appelez plutôt Free. Free vérifie que la référence objet n'a pas la valeur nil avant d'appeler Destroy.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

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

  3. #3
    Membre du Club
    Homme Profil pro
    Animateur commercial
    Inscrit en
    Août 2011
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Animateur commercial

    Informations forums :
    Inscription : Août 2011
    Messages : 47
    Points : 41
    Points
    41
    Par défaut
    Merci pour la réponse ShaiLeTroll. Merci d'avoir pointé les endroits ou je dois améliorer mon code.

    J'ai modifié mon code en ce qui concerne le bourrage de Zéro, j'ai utilisé FillChar et StrPLCopy
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FillChar(Filepath, SizeOf(Filepath), 0);
    StrPLCopy(Filepath,Chemin,128);
    J'ai re-déclaré ma variable vide au début de la procédure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream2.Position := Stream2.Size;
    Pour la déclaration de la position, en fait, il faut que je me place à la fin de mon fichier pour copier l'un des fichiers imbriqués (qui se trouve dans le stream1) dans le fichier global (Vers le fichier Stream2).
    L'écriture n'est pas linéaire car je copie mon fichier en fin de fichier, puis je remonte dans le début du fichier pour déclarer sa position d'ou le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream2.Position := 4 + ((i3)*128);
    Le calcul est bon, car les variables sont copiés au bon endroit.

    J'ai fait une copie d'écran du résultat. Pour la première boucle, il n'y a pas de souci sur l'écriture de la variable Taille, par contre pour les boucles suivantes, j'ai une erreur sur l'écriture de la variable taille, alors que dans le showmessage tout est ok.


    Je ne comprend pas pourquoi il ne m'écrit pas la variable qui est correctement affiché :-/

  4. #4
    Membre du Club
    Homme Profil pro
    Animateur commercial
    Inscrit en
    Août 2011
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Animateur commercial

    Informations forums :
    Inscription : Août 2011
    Messages : 47
    Points : 41
    Points
    41
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream2.Position := 4 + ((i3)*128);
    Tu avais raison ShaiLeTroll s'est ma formule qui est fausse et j'avais aussi un souci avec cette ligne Stream2.Write(Vide,4);. Merci beaucoup pour ton coup de main qui m'a permis d'améliorer mon code.

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

Discussions similaires

  1. DoCmd.GoToRecord et détection des erreurs de saisie
    Par aba_tarn dans le forum VBA Access
    Réponses: 12
    Dernier message: 26/07/2007, 08h44
  2. [VBA-E]Gèrer les erreurs de saisie de dates
    Par nicocomumu dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 03/05/2007, 16h08
  3. Formulaire | champ en surbrillance si erreur de saisie
    Par jiojioforever dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 10/11/2006, 09h59
  4. Réponses: 6
    Dernier message: 08/10/2006, 16h49
  5. Eviter les erreurs de saisie
    Par julo56 dans le forum C++
    Réponses: 5
    Dernier message: 06/06/2006, 00h04

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