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

C++Builder Discussion :

Ecriture et Lecture de fichiers binaire avec « fonctions de haut niveau » sous Borland C++ Builder XE [Débutant]


Sujet :

C++Builder

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2011
    Messages : 20
    Points : 20
    Points
    20
    Par défaut Ecriture et Lecture de fichiers binaire avec « fonctions de haut niveau » sous Borland C++ Builder XE
    Bonjour à tous, et à toutes,

    Arrivant de .Net C# je démarre un projet en Borland C++ Builder (Embarcadero RAD Studio XE v2010 [v15.0.3953.35171]), et bien entendu j’ai du mal à retrouver mes petits…

    D’où ma question toute bête : Je cherche à écrire et lire des fichiers binaires, mais je ne sais pas comment m’y prendre en C++ Builder.
    Plus précisément je cherche a utiliser des fonctions de haut niveau, plutôt que les classiques fopen, fwrite, fseek, fclose/FileOut.write, FileOut .close, FileIn.read, FileIn.close de C++.

    Je pensais utiliser des classes de Borland du genre FileCreate & FileWrite, voir les TfileStream, mais en cherchant sur le forum et dans l’aide de C++ Builder, je constate qu’a priori on ne peut pas écrire des fichiers texte avec ces fonctions… Du coup je reste bête, et je me dis que je dois louper un truc.



    Est-ce que quelqu’un aurait un bout de code, voire même un exemple d’écriture et de lecture dans un fichier binaire avec des fonctions de haut niveau en Borland C++ Builder à me transmettre?

    Merci d’avance à tous et à toute pour votre aide

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Citation Envoyé par otacon ghost Voir le message
    Je pensais utiliser des classes de Borland du genre FileCreate & FileWrite, voir les TfileStream, mais en cherchant sur le forum et dans l’aide de C++ Builder, je constate qu’a priori on ne peut écrire du des fichiers texte avec c’est fonctions… Du coup je reste bête, et je me dis que je dois louper un truc.
    TFileStream c'est le composant pour écrire et lire du fichier binaire !
    La méthode Write peut écire n'importe quel buffer !

    Citation Envoyé par otacon ghost Voir le message
    je constate qu’a priori on ne peut pas écrire des fichiers texte avec ces fonctions…
    Effectivement, l'écriture en mode Texte via TFileStream est un peu subtile !
    Mieux vaut utiliser ReadLn et WriteLn pour du fichier texte !

    Il est triste que TStream de Delphi reste moins évolué que celui de Lazarus qui fourni en standard du WriteByte, WriteInteger, WriteAnsiString

    TFileStream est un objet où il faut savoir la structure de son fichier !
    Si tu veux des fonctions comme WriteInteger ou WriteString comme dans le Writer du C#, il te faut utiliser le TWriter une classe utilisé pour le Format DFM mais pour un format binaire libre le TStreamWriter devrait te plaire, je ne l'ai jamais utilisé, cela n'existe pas en BCB2007

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream.Write(i, sizeof(i)); // i pouvant être BYTE, SHORT ou LONG
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream.Write(S.c_str(), S.Length * sizeof(Char)); // je ne sais pas si c_str() existe en XE, je suis en C++ 2007 non unicode, je n'ai pas encore utilisé TFileStream en C++ mais plutôt en Delphi
    Pour la lecture, soit tu sais le nombre d'octet à l'avance, pense que pour l'unicode le nombre d'octet est le double du nombre de caractère ou alors tu gère un entier contenant la longueur de la chaine qui suit ... tout dépend du format binaire !

    Sinon, en C++, fini la mémoire protégée !
    Si ton fichier à une structure bien défini de longueur fixe, tu peux déclarer une structure, tu peux directement lire le fichier et remplir la structure, ensuite tu peux caster cette structure pour avoir plusieurs types de données ou alors utiliser l'union !

    Si j'étais toi, j'utiliserais d'ailleurs plutôt Delphi que C++Builder, après tout le second n'est qu'une "surcouche" C++ au dessus de la VCL Delphi, et maintenant avec les Génériques Delphi, on a plus besoin de la la STL (qui j'ai découvert récemment en C++Builder)
    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 chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut
    Si la portabilité n'est pas importante, tu peux également utiliser les fonctions de l'API win32
    WriteFile, WriteFileX,ReadFile.ReadFileX
    Ce fonctions sont assez évoluées, elle permettent entre autre la lecture et l'écriture sur le disque, des fichiers, des IO, des MailSlots, Sockets ......

    je te laisse le soin de lire l'aide appropriée livrée avec des exemples
    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  4. #4
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2011
    Messages : 20
    Points : 20
    Points
    20
    Par défaut
    Bonjour à tous les deux et merci pour vos réponses.

    @DjmSoftware :
    Si la portabilité n'est pas importante, tu peux également utiliser les fonctions de l'API win32
    WriteFile, WriteFileX,ReadFile.ReadFileX
    Ce fonctions sont assez évoluées, elle permettent entre autre la lecture et l'écriture sur le disque, des fichiers, des IO, des MailSlots, Sockets ......
    Justement dans mon app je dois éviter l’API Win32, car cette app doit être portable sur d’autres OS que Windows…
    Sinon c’est clair que je serais passé par ce genre de fonction!
    Mais l’info est bonne à prendre pour d’autres personnes qui seraient dans ce cas. Merci pour l’info en tout cas.



    @ShaiLeTroll :
    En fait ce qui m’as mis le doute TFileStream, c’est que, par exemple, pour le TFileStream.Create on ne spécifie pas si l’on est en texte, binaire ou autre, donc je me suis dit que c’était mort pour cette classe... Cherchons autre chose...

    Concernant le TWriter c’est typiquement le genre de classe que je cherchais!
    Comme je connais la structure de mon fichier binaire (à écrire et à lire), cette classe fera très bien mon affaire.

    Par contre je ne sais pas comment tu fais pour trouver toutes c'est infos... Je galère avec l'aide de C++ Builder...
    Rendez moi mon MSDN et mon C# svp! lol

    Sinon, en C++, fini la mémoire protégée !
    Si ton fichier à une structure bien défini de longueur fixe, tu peux déclarer une structure, tu peux directement lire le fichier et remplir la structure, ensuite tu peux caster cette structure pour avoir plusieurs types de données ou alors utiliser l'union !
    Pour ce point je serais curieux de savoir comment tu fais ça?
    Tu n’aurais pas un exemple sous la main par hasard?


    Si j'étais toi, j'utiliserais d'ailleurs plutôt Delphi que C++Builder, après tout le second n'est qu'une "surcouche" C++ au dessus de la VCL Delphi, et maintenant avec les Génériques Delphi, on a plus besoin de la la STL (qui j'ai découvert récemment en C++Builder)
    Alors là je suis coincé, car c’est Borland C++ Builder ou rien : C’est un choix imposé et fixe… Sinon je serais passé directement à C# lol


    En tout cas une fois de plus merci pour toutes c’est infos et exemples!

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Citation Envoyé par otacon ghost Voir le message
    Justement dans mon app je dois éviter l’API Win32, car cette app doit être portable sur d’autres OS que Windows…
    En C++Builder, tu produis forcément du Windows !
    Tu as XE (V15) donc Win32
    Attends XE2 (V16) pour Win32, Win64 ou MacOS X
    Sinon oublie C++ Builder, ce n'est pas portable !

    Citation Envoyé par otacon ghost Voir le message
    Concernant le TWriter c’est typiquement le genre de classe que je cherchais!
    Comme je connais la structure de mon fichier binaire (à écrire et à lire), cette classe fera très bien mon affaire.
    Attention TWriter c'est exclusivement le Format DFM
    Toi, tu utilisera TBinaryWriter, ça doit être une nouvelle classe de XE
    Tu as de la chance !

    Je vais sur DOC WIKI embarcadero

    EDIT : Comme je n'avais fait que l'écriture de packed record en Delphi avec BlockWrite (pascal), WriteFile (API) ou FileStream.Write, je me suis dit que c'était l'occasion de l'essayer en C++, voici mon 1er essai, bon c'est pareil en Delphi ou en C++ mais c'est sympa de réapprendre ses bases !
    Ouvre le ficher avec UltraEdit pour constater son contenu !

    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
    143
    144
    145
    146
    147
    148
     
     
    {
      TFileStream * FS = new TFileStream(ChangeFileExt(Application->ExeName, ".bin"), fmCreate);
      try
      {
        #pragma option push -a1
        struct
        {
          int X;
          int Y;
          char ChaineAnsi[100];
          wchar_t ChaineUTF16[100];
          double D;
        } WRec;
        #pragma option pop
     
        ZeroMemory(&WRec, sizeof(WRec));
        WRec.X = 1;
        WRec.Y = -1;
        AnsiString Sa = "Bonjour ! Il fait moche cet été !";
        StrLCopy(WRec.ChaineAnsi, Sa.c_str(), Sa.Length());
        UnicodeString Su = "Au Revoir ! On dirait l'automne de l'hémisphère nord, allons cueillir des châtaignes !";
        StrLCopy(WRec.ChaineUTF16, Su.c_str(), Su.Length());
        WRec.D = 1.01;
     
        FS->Write(&WRec, sizeof(WRec));
      }
      __finally
      {
        delete FS;
      }
     
      FS = new TFileStream(ChangeFileExt(Application->ExeName, ".bin"), fmOpenRead);
      try
      {
        #pragma option push -a1
        struct
        {
          short A;
          short B;
          short C;
          unsigned short D;
          AnsiChar ChaineOne[50];
          AnsiChar ChaineTwo[50];
          WideChar ChaineThree[50];
          WideChar ChaineFor[50];
          double R;
        } RRec;
        #pragma option pop
     
        FS->Read(&RRec, sizeof(RRec));
     
        ShowMessage(RRec.A);
        ShowMessage(RRec.B);
        ShowMessage(RRec.C);
        ShowMessage(RRec.D);
        ShowMessage(RRec.ChaineOne);
        ShowMessage(RRec.ChaineTwo);
        ShowMessage(RRec.ChaineThree); // utilise StrLen donc comme pas de 00 00 cela déborde sur ChaineFor
        ShowMessage(RRec.ChaineFor);
        ShowMessage(RRec.R);
      }
      __finally
      {
        delete FS;
      }
     
      ShowMessage("TBinaryReader ANSI");
     
      TBinaryReader * BR = new TBinaryReader(ChangeFileExt(Application->ExeName, ".bin"), TEncoding::Default);
      try
      {
        ShowMessage(BR->ReadInt32());
        ShowMessage(BR->ReadInt32());
     
        TCharArray CA = BR->ReadChars(100);
        TStringBuilder *SB = new TStringBuilder();
        try
        {
          SB->Append(CA);
          ShowMessage(SB->ToString());
        }
        __finally
        {
          delete SB;
        }
     
        CA = BR->ReadChars(200);
        SB = new TStringBuilder();
        try
        {
          SB->Append(CA);
          ShowMessage(SB->ToString());
        }
        __finally
        {
          delete SB;
        }
     
        ShowMessage(BR->ReadDouble());
     
      }
      __finally
      {
        delete BR;
      }
     
      ShowMessage("TBinaryReader Unicode");
     
      BR = new TBinaryReader(ChangeFileExt(Application->ExeName, ".bin"), TEncoding::Unicode);
      try
      {
        ShowMessage(BR->ReadInt32());
        ShowMessage(BR->ReadInt32());
     
        TCharArray CA = BR->ReadChars(50);
        TStringBuilder *SB = new TStringBuilder();
        try
        {
          SB->Append(CA);
          ShowMessage(SB->ToString());
        }
        __finally
        {
          delete SB;
        }
     
        CA = BR->ReadChars(100);
        SB = new TStringBuilder();
        try
        {
          SB->Append(CA);
          ShowMessage(SB->ToString());
        }
        __finally
        {
          delete SB;
        }
     
        ShowMessage(BR->ReadDouble());
     
      }
      __finally
      {
        delete BR;
      }
    }
    Tu notes l'utilisation complexe de ReadChars !
    Effectivement ReadString utilise un format spécial pour définir une longueur variable, cette longueur est encodé sur 1 à 5 octets, c'est assez étrange et donc inutilisable dans la pratique (en général, la lecture binaire c'est pour des fichiers qui viennent d'ailleurs ... je comprends pas ce choix d'un ReadString aussi tordu)
    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

  6. #6
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2011
    Messages : 20
    Points : 20
    Points
    20
    Par défaut
    Re ShaiLeTroll ,

    Merci pour ce bel exemple! Je vais regarder ça de plus près

    [Edit:] C'est du tout bon! C'est exactement ce que je cherchais à faire.
    Encore merci pour le coup de main ShaiLeTroll

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

Discussions similaires

  1. Lecture de fichiers binaire avec Get
    Par NVCfrm dans le forum Contribuez
    Réponses: 0
    Dernier message: 26/07/2013, 04h42
  2. Réponses: 4
    Dernier message: 25/05/2011, 16h38
  3. Lecture fichier binaire avec fLit
    Par kinouseb dans le forum WinDev
    Réponses: 4
    Dernier message: 07/07/2007, 00h24
  4. Lecture de fichier binaire fortran avec java
    Par bigbrother737 dans le forum Langage
    Réponses: 1
    Dernier message: 11/05/2007, 11h34
  5. Ecriture et lecture de fichiers
    Par nozvad dans le forum Général Python
    Réponses: 4
    Dernier message: 12/10/2004, 17h47

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