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 XE7 ] modifier une valeur hexa dans un fichier bin


Sujet :

Delphi

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut [Delphi XE7 ] modifier une valeur hexa dans un fichier bin
    Bonjour A tous , je débute en delphi , je voudrais changer les valeurs HEX d'un fichier binaire , je peux le faire avec un hex editeur , par contre je veux créer un bouton et changer depuis un TEdit .

    mon TEdit : a une valeur de 15 caractère composé des lettres hexa : 0123456789 ABCDEF.
    je veux écrire directement sur le fichier bin
    voici mon code que je suis entrain de faire :

    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Value, I: integer;
      value2 : char;
      Reader: TBinaryReader;
      Stream: TFileStream;
      Writer: TBinaryWriter;
      byteArray : array of byte;
     
    begin
    Stream := TFileStream.Create('F:\test\file.bin', fmOpenRead or fmShareDenyWrite);
    try
      Reader := TBinaryReader.Create(Stream);
      try
        Value := Reader.ReadInteger;
        Edit1.Text:=IntToStr(Value);
        Memo1.Lines.Add(IntToStr(Value));
        value2:= Reader.ReadChar;
        Memo1.Lines.Add(value2);
        //byteArray := StringToBytes(Edit2.Text);
      finally
     
      Reader.Free;
      end;
    finally
      Stream.Free;
    end;

    actuellement la valeur en hex est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    8A 86 19 09 04 03 77 84
    en texte normalement c'est : je veux changer depuis le TEdit : par exemple :

    valeur en hex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    3A 05 10 32 54 76 98 00
    la question est comment je peux écrire directement les valeurs hex voulue directement sur le fichier bin ?
    Merci pour l'aide

  2. #2
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 614
    Points
    3 614
    Par défaut
    Tu peux ouvrir le fichier en mode binaire (assignfile, file open, ... ou blockread/blockwrite) et te positionner à l'emplacement que tu veux modifier.

    Et il te suffit de convertir ce qui est saisi en une série d'octets des valeurs correspondantes.

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par pprem Voir le message
    Tu peux ouvrir le fichier en mode binaire (assignfile, file open, ... ou blockread/blockwrite) et te positionner à l'emplacement que tu veux modifier.

    Et il te suffit de convertir ce qui est saisi en une série d'octets des valeurs correspondantes.
    un exemple en code serait super , Merci

  4. #4
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Bonjour j'ai un autre soucis j'ai trouvez comment lire avec le Blockread et assignfile comme l'a suggérer pprem par contre comment convertir chaque deux caractère en byte et écrire directement vers le fichier .

    voici mon code pour la lecture :

    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
     
    var
      myFile    : File;
      byteArray : array[1..8] of byte;
      oneByte   : byte;
      i, count  : Integer;
     
    begin
      // Try to open the Test.byt file for writing to
      AssignFile(myFile, 'F:\test\file.bin');
      // ReWrite(myFile, 4);   // Define a single 'record' as 4 bytes
     
      // Fill out the data array
      for i := 1 to 8 do
      byteArray[i] := i;
     
      // Write the data array to the file
      //BlockWrite(myFile, byteArray, 2);   // Write 2 'records' of 4 bytes
     
      // Close the file
      //CloseFile(myFile);
     
      // Reopen the file for reading
      //FileMode := fmOpenRead;
      Reset(myFile, 1);   // Now we define one record as 1 byte
     
      // Display the file contents
      // Start with a read of the first 6 bytes. 'count' is set to the
      // actual number read
      ShowMessage('Reading first set of bytes :');
      blockread(myFile, byteArray, 6, count);
     
      // Display the byte values read
      for i := 1 to count do
        ShowMessage(IntToStr(byteArray[i]));
     
      // Now read one byte at a time to the end of the file
      ShowMessage('Reading remaining bytes :');
      while not Eof(myFile) do
      begin
        blockread(myFile, oneByte, 1);   // Read one byte at a time
        ShowMessage(IntToStr(oneByte));
      end;
     
      // Close the file for the last time
      CloseFile(myFile);
    cordialement

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    Il y a une confusion entre la notion de binaire dans un fichier et la représentation Hexa

    BinToHex et HexToBin pour convertir un Texte type "3A 05 10 32 54 76 98 00" dans un TEdit


    lire ce sujet Conversion Image <> HEX


    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
     
    function BinFileToHexaString(const InFileName: TFileName): AnsiString;
    var
      FileStream: TFileStream;
      MemoryStream: TMemoryStream;
    begin
      FileStream := TFileStream.Create(InFileName, fmOpenRead );
      try
        if FileStream.Size > 0 then
        begin
          SetLength(Result, FileStream.Size * 2);
     
          MemoryStream := TMemoryStream.Create();
          try
            MemoryStream.CopyFrom(FileStream, FileStream.Size);
            MemoryStream.Position := 0;
     
            BinToHex(PAnsiChar(Integer(Stream.MemoryStream)), PAnsiChar(Result), MemoryStream.Size);
          finally
            MemoryStream.Free;
          end;
        end;
      finally
        FileStream.Free;
      end;
    end;
    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
    procedure HexaStringToBinFile(const OutFileName: string; const HexaText: string);
     
       function LowCharCase(C: Char): Char;
       asm
               CMP     AL,'A'
               JB      @@exit
               CMP     AL,'Z'
               JA      @@exit
               SUB     AL,'A' - 'a'
       @@exit:
       end;
     
    var
       HexaCleanText: string;
       HexaBuffer: array of Char;
       OutFile: file;
       I, Count: Integer;
    begin
       AssignFile(OutFile, OutFileName);
       Rewrite(OutFile, 1);
       try
          Count := 0;
          SetLength(HexaCleanText, Length(HexaText));
          ZeroMemory(@HexaCleanText[1], Length(HexaCleanText));
          for I := 1 to Length(HexaText) do
          begin
             if HexaText[I] in ['0'..'9', 'A'..'F', 'a'..'f'] then
             begin
                Inc(Count);
                HexaCleanText[Count] := LowCharCase(HexaText[I]);
             end;
          end;
          Count := Count div 2;
          SetLength(HexaBuffer, Count);
          HexToBin(@HexaCleanText[1], @HexaBuffer[0], Count);
          BlockWrite(OutFile, HexaBuffer[0], Count);
       finally
          CloseFile(OutFile);
       end;
    end;

  6. #6
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    un exemple comment l'utilisez dans mon code ? je suis débutant.
    j'ai une erreur de l'ide dans la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HexToBin(@HexaCleanText[1], @HexaBuffer[0], Count);
    [dcc32 Error] Unit2.pas(90): E2251 Ambiguous overloaded call to 'HexToBin'
    System.Classes.pas(12544): Related method: function HexToBin(PAnsiChar; Pointer; Integer): Integer;
    System.Classes.pas(12539): Related method: function HexToBin(PWideChar; Pointer; Integer): Integer;

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 871
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HexToBin( PAnsiChar( @HexaCleanText[1]), @HexaBuffer[0], Count);
    probablement, pour lui indiquer le type de chaîne passée (Ansi : caractères ASCII codés sur un octet, ou Wide : caractères Unicode codés sur 2 octets).

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    Citation Envoyé par coolirc Voir le message
    un exemple comment l'utilisez dans mon code ? je suis débutant.
    j'ai une erreur de l'ide dans la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HexToBin(@HexaCleanText[1], @HexaBuffer[0], Count);
    Effectivement, dans la fonction HexaStringToBinFile de 2008, le type que string pour HexaCleanText et array of Char pour HexaBuffer c'est implicitement du Ansi D7

    Alors que BinFileToHexaString a été écrite en 2011 sous RAD Studio 2007, je dirais mais on voit qu'elle a été reflechi pour gérer de l'ANSI dans une application Unicode, j'étais en pleine migration de BCB 2006 vers BCB XE2
    Mais cela restait un code théorique à travailler

    Ces fonctions écrites uniquement pour le forum trainent ici ou là et ne pas en phase de version.

    Voici un couple compatible même si cela utilise deux méthodes différentes et que c'est très très loin d'être optimisé pour la charge mémoire

    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
    procedure HexaStringToBinFile(const OutFileName: string; const HexaText: string);
     
       function LowCharCase(C: Char): Char;
       asm
               CMP     AL,'A'
               JB      @@exit
               CMP     AL,'Z'
               JA      @@exit
               SUB     AL,'A' - 'a'
       @@exit:
       end;
     
    var
       HexaCleanText: string;
       HexaBuffer: array of AnsiChar;
       OutFile: file;
       I, Count: Integer;
    begin
       AssignFile(OutFile, OutFileName);
       Rewrite(OutFile, 1);
       try
          Count := 0;
          SetLength(HexaCleanText, Length(HexaText));
          ZeroMemory(@HexaCleanText[1], Length(HexaCleanText));
          for I := 1 to Length(HexaText) do
          begin
             if CharInSet(HexaText[I], ['0'..'9', 'A'..'F', 'a'..'f']) then
             begin
                Inc(Count);
                HexaCleanText[Count] := LowCharCase(HexaText[I]);
             end;
          end;
          Count := Count div 2;
          SetLength(HexaBuffer, Count);
          HexToBin(PWideChar(@HexaCleanText[1]), PAnsiChar(@HexaBuffer[0]), Count);
          BlockWrite(OutFile, HexaBuffer[0], Count);
       finally
          CloseFile(OutFile);
       end;
    end;
     
    function BinFileToHexaString(const InFileName: TFileName): string;
    var
      FileStream: TFileStream;
      MemoryStream: TBytesStream;
      Buffer: TBytes;
    begin
      FileStream := TFileStream.Create(InFileName, fmOpenRead );
      try
        if FileStream.Size > 0 then
        begin
          MemoryStream := TBytesStream.Create();
          try
            MemoryStream.CopyFrom(FileStream, FileStream.Size);
            MemoryStream.Position := 0;
     
            SetLength(Buffer, FileStream.Size * 2);
            BinToHex(MemoryStream.Bytes, 0, Buffer, 0, MemoryStream.Size);
            Result := TEncoding.ANSI.GetString(Buffer);
          finally
            MemoryStream.Free;
          end;
        end;
      finally
        FileStream.Free;
      end;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      HexaStringToBinFile('e.txt', 'FF AA 00 EE 99');
      Edit1.Text := BinFileToHexaString('e.txt');
    end;

  9. #9
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Bonsoir

    Merci pour les réponses , j'ai tester avec le dernier code ça marche si on a fichier qui contient seulement les données hexa seulement . par contre si je veux me positionner dans un autre fichier et lire la valeur de 10 bytes par exemple je reçois une texte vide:

    par exemple si je fait un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MemoryStream.Seek($621, soBeginning);
    ou
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MemoryStream.Position := $621;
    dans le fonction : BinFileToHexaString
    ça marche pas , comment je peux me positionner avec la fonction BinFileToHexaString et lire seulement 10 bytes ou 8 depuis le milieu du fichier ?
    Cordialement

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    Citation Envoyé par coolirc Voir le message
    ...on a fichier qui contient seulement les données hexa seulement ...
    Un fichier c'est toujours une suite de 010101 donc représentable en Hexa, votre phrase ci-dessus n'a pas de sens, tout fichier es représentable en Hexa
    Il aurait été préférable d'évoquer que le fichier est partiellement du Texte (encodage Ansi, UTF8 ou autre) et d'autres parties sont en Binaire simple, des données comme des Integer ou Float... le parfait exemple est le DFM Binaire.
    Sachant que le Texte c'est aussi un Binaire mais dont le sens est exploité de façon spécifique.


    BinFileToHexaString utilise une version bien précise de BinToHex avec des TBytes, un minimum d'effort et lire l'aide serait pas mal !
    Il y a quand même un paramètre BufOffset
    Mais c'est loin d'être le mieux


    MemoryStream.Seek et MemoryStream.Position n'ont aucun effet puisque cela utilise MemoryStream.Bytes qui retourne un tableau de l'ensemble de la donnée, il faut mieux analyser le code.
    Faudrait mieux maitriser les classes RTL avant de bricoler
    Prenez le temps de décortiquer le code que l'on vous fourni.


    Vous n'avez pas vu FileStream ?
    Pourquoi lire tout le fichier en mémoire si l'on ne veut que 10 octets


    J'espère que vous allez décortiquer cette fonction pour mieux la comprendre

    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
    function BinFileToHexaString(const InFileName: TFileName; Offset, Count: Integer): string;
    var
      FileStream: TFileStream;
      Buffer: AnsiString;
    begin
      FileStream := TFileStream.Create(InFileName, fmOpenRead );
      try
        if FileStream.Size >= Offset + Count then
        begin
          FileStream.Seek(Offset, soBeginning);
          SetLength(Buffer, Count);
          FileStream.Read(Buffer[1], Count);
     
          SetLength(Result, Count * 2);
          BinToHex(PAnsiChar(Buffer), PWideChar(Result), Count);
        end;
      finally
        FileStream.Free;
      end;
    end;

  11. #11
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Bonjour
    Merci pour votre réponse rapide et désolé je suis entrain d'apprendre donc j'ai pas pu comprendre totalement le code . je vais essayer de bricoler un peux. je suis entrain de me battre avec l'autre fonction HexaStringToBinFile , qui utilise actuellement assignfile et rewrite file qui efface totalement le fichier et écrit seulement les 8 bytes et efface tout le reste, peut ont faire un TFileStream aussi sur la fonction HexaStringToBinFile ?

    Cordialement

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    L'écrirture partielle dans un fichier est un peu plus complexe

    En fait, il est plus simple de lire tout le fichier, de remplacer la section dans la chaine puis tout réécrire dans le cas d'une insertion plus longue que l'originale.
    Tout à fait valable pour fichier de quelques Mo
    Ensuite faudra penser à une lecture Ecriture avec Buffer ... et là ça se corse nettement, c'est con, je l'ai écrit pour un projet récemment mais j'ai finalement fait plus simple par un Load\Save Complet pour gérer une conversion Ansi -> UTF8+BOM au passage

    Dans le cas particulier d'un remplacement de taille égale, suffit de remplacer Rewrite par Reset, de faire un Seek et modifier via BlockWrite la section souhaitée, il n'y a que deux lignes à changer

    et en fait pour TFileStream, la modification c'est juste le Seek mais surtout fmOpenReadWrite, idem juste deux lignes qui change pour passer d'une fonction de Lecture à Ecriture, après reste la partie épurage du Hexa


    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
     
    procedure HexaStringToBinFile(const OutFileName: string; const HexaText: string); overload;
     
       function LowCharCase(C: Char): Char;
       asm
               CMP     AL,'A'
               JB      @@exit
               CMP     AL,'Z'
               JA      @@exit
               SUB     AL,'A' - 'a'
       @@exit:
       end;
     
    var
       HexaCleanText: string;
       HexaBuffer: array of AnsiChar;
       OutFile: file;
       I, Count: Integer;
    begin
       AssignFile(OutFile, OutFileName);
       Rewrite(OutFile, 1);
       try
          Count := 0;
          SetLength(HexaCleanText, Length(HexaText));
          ZeroMemory(@HexaCleanText[1], Length(HexaCleanText));
          for I := 1 to Length(HexaText) do
          begin
             if CharInSet(HexaText[I], ['0'..'9', 'A'..'F', 'a'..'f']) then
             begin
                Inc(Count);
                HexaCleanText[Count] := LowCharCase(HexaText[I]);
             end;
          end;
          Count := Count div 2;
          SetLength(HexaBuffer, Count);
          HexToBin(PWideChar(@HexaCleanText[1]), PAnsiChar(@HexaBuffer[0]), Count);
          BlockWrite(OutFile, HexaBuffer[0], Count);
       finally
          CloseFile(OutFile);
       end;
    end;
     
    procedure HexaStringToBinFile(const OutFileName: string; const HexaText: string; Offset: Integer); overload;
     
       function LowCharCase(C: Char): Char;
       asm
               CMP     AL,'A'
               JB      @@exit
               CMP     AL,'Z'
               JA      @@exit
               SUB     AL,'A' - 'a'
       @@exit:
       end;
     
    var
       HexaCleanText: string;
       HexaBuffer: array of AnsiChar;
       OutFile: file;
       I, Count: Integer;
    begin
       AssignFile(OutFile, OutFileName);
       Reset(OutFile, 1);
       try
          Count := 0;
          SetLength(HexaCleanText, Length(HexaText));
          ZeroMemory(@HexaCleanText[1], Length(HexaCleanText));
          for I := 1 to Length(HexaText) do
          begin
             if CharInSet(HexaText[I], ['0'..'9', 'A'..'F', 'a'..'f']) then
             begin
                Inc(Count);
                HexaCleanText[Count] := LowCharCase(HexaText[I]);
             end;
          end;
          Count := Count div 2;
          SetLength(HexaBuffer, Count);
          HexToBin(PWideChar(@HexaCleanText[1]), PAnsiChar(@HexaBuffer[0]), Count);
     
          Seek(OutFile, Offset);
          BlockWrite(OutFile, HexaBuffer[0], Count);
       finally
          CloseFile(OutFile);
       end;
    end;
     
    function BinFileToHexaString(const InFileName: TFileName): string; overload;
    var
      FileStream: TFileStream;
      MemoryStream: TBytesStream;
      Buffer: TBytes;
    begin
      FileStream := TFileStream.Create(InFileName, fmOpenRead );
      try
        if FileStream.Size > 0 then
        begin
          MemoryStream := TBytesStream.Create();
          try
            MemoryStream.CopyFrom(FileStream, FileStream.Size);
            MemoryStream.Position := 0;
     
            SetLength(Buffer, FileStream.Size * 2);
            BinToHex(MemoryStream.Bytes, 0, Buffer, 0, MemoryStream.Size);
            Result := TEncoding.ANSI.GetString(Buffer);
          finally
            MemoryStream.Free;
          end;
        end;
      finally
        FileStream.Free;
      end;
    end;
     
    function BinFileToHexaString(const InFileName: TFileName; Offset, Count: Integer): string; overload;
    var
      FileStream: TFileStream;
      Buffer: AnsiString;
    begin
      FileStream := TFileStream.Create(InFileName, fmOpenRead );  
      try
        if FileStream.Size >= Offset + Count then
        begin
          FileStream.Seek(Offset, soBeginning);
          SetLength(Buffer, Count);
          FileStream.Read(Buffer[1], Count);
     
          SetLength(Result, Count * 2);
          BinToHex(PAnsiChar(Buffer), PWideChar(Result), Count);
        end;
      finally
        FileStream.Free;
      end;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      HexaStringToBinFile('e.txt', 'FF AA 00 EE 99 12 34 56');
      Edit1.Text := BinFileToHexaString('e.txt');
      Edit2.Text := BinFileToHexaString('e.txt',3, 2);
      HexaStringToBinFile('e.txt', '76 54', 3);
      Edit3.Text := BinFileToHexaString('e.txt',3, 2);
      Edit4.Text := BinFileToHexaString('e.txt');
    end;

  13. #13
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Super , ça marche super bien .
    j'ai fait un Tbutton pour lire depuis le fichier Bin et afficher sur un Tedit1 en utilisant la fonction BinFileToHexaString
    et un autre Tbutton pour Ecrire directement la valeur hexa sur un Tedit2 en utilisant la fonction HexaStringToBinFile , j'ai fait comme vous avez suggérer puisque la valeur est fixe j'ai remplacer rewrite par reset.
    j'ai une autre fonction aussi qui converti chaque deux caractère en hexa depuis un simple texte par contre le seul soucis est que je veux afficher le A dans le deuxième caractère par exemple comme ça :
    en utilisant la fonction Reverse to Hex j'obtiens ceci : le A s'affiche avant le dernier caractère .
    je peux utiliser un chiffre pair par exemple supprimer le premier 8 et j’obtiendrais une conversion simple et j'ajouterais seulement un 8A au début. mais avec la fonction corrigé ça serait mieux.
    comment faire pour afficher le A en deuxième position . exemple . 8A68....
    fonction actuelle
    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
    function ReverseEachTwoChars(AInput : string) : string;
    var
      i : integer;
    begin
      if(Odd(Length(AInput))) then
      begin
        SetLength(AInput, Length(AInput)+1);
        AInput[Length(AInput)] := 'A';
     
      end;
     
      SetLength(Result, Length(AInput));
      i := 1;
      while(i < Length(Result)) do
      begin
        Result[i] := AInput[i + 1];
        Result[i + 1] := AInput[i];
        Inc(i, 2);
      end;
    end;

  14. #14
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    Sinon c'est il faut modifier un Int64 pourquoi ne pas passer en binaire pur au lieu du Hexa ?
    Cela gérera les problèmes de Little Endian

  15. #15
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    La valeur Hexa est essentiel car on traite d’abord la valeur hexa existante dans le fichier a travers le TFileStream et le Seek après on prends la valeur hexa voulue depuis un TEdit après une conversion depuis le Text en Hexa et on finient par replacer la valeur changé dans le fichier de destination.

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 871
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par nombre ou texte ?
    douze
    Quand ShaiLeTroll écrit que la valeur n'est pas en hexa, il a raison : c'est ton choix de la traiter ainsi car c'est plus parlant pour toi et/ou que tu sais que ça a du sens de la représenter ainsi, mais ça peut sûrement se faire autrement, et peut-être même de façon plus efficace ou moins piégeuse.

  17. #17
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Tout a fait d'accord avec vous , je ne dit pas le contraire , il existe plusieurs façon de traiter la solution dont ShaiLeTroll a beacoup aider avec ses deux fonctions et explications qui fonctionnent a 100% .

    Merci pour votre aide

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 09/07/2020, 13h03
  2. Réponses: 9
    Dernier message: 12/08/2008, 16h50
  3. Comment chercher une chaine hexa dans un fichier ?
    Par marchphi dans le forum Langage
    Réponses: 4
    Dernier message: 26/02/2008, 07h59
  4. Remplacement d'une valeur hexa dans une chaine
    Par raoulchatigre dans le forum C++
    Réponses: 7
    Dernier message: 18/09/2006, 16h27
  5. Réponses: 4
    Dernier message: 29/03/2006, 08h22

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