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 :

Format de fichier extensible


Sujet :

C++Builder

  1. #1
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut Format de fichier extensible
    Bonjour,

    Je cherche un moyen facile (code, composant, astuce, etc.) pour cr�er un nouveau format de fichier extensible. Ce fichier fait partie d'un programme qui est en cours d'�volution ... pour une question de temps il est d�j� distribu� en l'�tat au client.
    J'avais pens� � utiliser un TIniFile. En effet, on peut ajouter des sections comme on le veut. Elles sont ignor�es par les anciens programmes et si le fichier a �t� sauv�s avec un ancien programme on sait quand m�me l'ouvrir dans un nouveau (la valeur de la cl� �tant remplac�e tout simplement par une valeur par d�faut).
    Le probl�me c'est que le fichier doit se comporter comme une archive. Il doit pouvoir stocker d'autres fichiers (<10ko). J'avais pens� les sauver en stream dans le fichier Ini mais tous les carat�res ASCII ne passent pas ... de plus, � mon humble avis, il doit y avoir une mani�re plus jolie de g�rer tout �a! Peut-�tre devrais-je me tourner du c�t� du XML mais je n'y connais strictement rien ...

    Un grand merci d'avance!
    Cordialement,
    Rodrigue

  2. #2
    Membre �m�rite
    Inscrit en
    Juin 2005
    Messages
    644
    D�tails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Par d�faut
    J'ai 2 types de solutions l'une est relative � des fichiers textes dont les lignes sont du type Identifiant = valeur du type de certain ficiers ini. Il est tr�s facile alors d'ajouter les lignes nouvelles en ajoutant de nouveaux identifiants. L'autre est relative � des fichiers binaires ou on lit le fichier jusqu'au bout. Si une novelle version comporte plus de donn�es alors capter l'erreur en lecture � partir d'un certain stade pour donner des valeurs par d�faut aux nouvelles donn�es. En fin d'execution sauver lea nouvelle structure et le tout est dit.

  3. #3
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    Bonjour,

    J'aime bien l'id�e du fichier Ini ! Notamment pour sa simplicit� ... Le probl�me comme je le dis dans mon premier message :
    Le probl�me c'est que le fichier doit se comporter comme une archive. Il doit pouvoir stocker d'autres fichiers (<10ko). J'avais pens� les sauver en stream dans le fichier Ini mais tous les carat�res ASCII ne passent pas
    Je n'arrive pas � sauver le stream comme un �l�ment unique dans le fichier Ini. Peut-�tre avez-vous une solution ?

    Maintenant quant � la solution du fichier binaire, je la trouve tr�s difficile (p-e que je me trompe ).

    Cordialement,
    Rodrigue

  4. #4
    Membre �m�rite
    Inscrit en
    Juin 2005
    Messages
    644
    D�tails du profil
    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 644
    Par d�faut
    Un fichier binaire est T R E S facile � manipuler sutout pour des donn�es structur�es. Il est + dense qu'un fichier texte, on n'y fait pas d'eereur d'arroudi sur les float,... Seul petit inconvenient : on ne peut pas facilement l'editer "� la main".
    Il est alors quasi im�diat de pouvoir aller lire/�crire le bloc No n en calculant l'offset, de se d�placer de x blocs ou de pointer sur un element quelconque de l'un des blocs.
    Lors d'un changement de version si la nouvelle version contient plus de data � stocker il est + facile de concerver toute la 1er partie commune, de detecter la fin de fichier et compl�ter � la 1er execution de la novelle version.
    D'experience (25 ans de programation) je sais qu'il est aussi nettement preferable de noter le no de version en d�but de fichier. cela permet au soft de savoir comment d�coder la suite sans perte de donn�e ou risque de m�lange. On est aussi quitte de la contrainte d'une compatibilite ascendante: si une novelle version du soft voit un fichier qui n'est pas de sa version, pas de chargement direct mais appel � transcodeur que le developpeur ecrit sans mal connaissant les structures des 2 versions impliqu�es.


    en C++ ouverture en r��criture

    FILE *f; f = fopen ( C,"wb"); (C char[] )
    voir les ordres du type
    SEEK_SET 0 Seeks from beginning of file
    SEEK_CUR 1 Seeks from current position
    SEEK_END 2 Seeks from end of file
    avec int fseek(f, offset, whence); pour aller en un point quelconque du fichier
    en lecture utiliser fread(Buffer,nombre,taille_element,f); (Buffer est une adresse)
    la taille d'un element s'obtient avec la fonction sizeof(XXX);
    pour lire et completer utiliser fopen(C,"rb+");
    bien entendu ne pas oublier fclose(f);

    pour rappel apres f=fopen(C,"rb"); on a la taille du fichier via
    taille = filelength(fileno(f)); // si fopen a march� et donc f != NULL

    tout cela est tres bien document� sous borland avec les mots clef fopen, fseek, fclose.

    exemple tres simple ecrit "� la va-vite" ici pour illustrer => il manque peut-etre un ; ou 1 parenth�ze!


    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
     
    struct Wave_File_Header
            {
            char                    RIFF[4]; //"RIFF" in ASCII form
            long                    Data_Size_plus_36; // filesize-8 = nbr data * bitsperdata+ 36
            char                    WAVE[4]; // lettres "WAVE"
            char                    fmt[4]; // lettress "fmt "
            long                    Remain_in_Chunk1; // 16 en format  PCM .
                                    // ce qui reste du Subchunk après ce nombre .
                                    // = audioformat+numchanel+samplerate+byterate+blockalign+bitpersample
                                    // =2+2+4+4+2+2 = 16
            short                   AudioFormat; //  PCM = 1 (i.e. Linear quantization) Values other than 1 indicate some form of compression.
            short                   NumChannels; //  Mono = 1, Stereo = 2, etc.
            long                    SampleRate;//       8000, 44100, etc.
            long                    ByteRate; // SampleRate * NumChannels * BitsPerSample/8
            short                   BlockAlign; // NumChannels * BitsPerSample/8
            short                   BitsPerSample; //     8 bits = 8, 16 bits = 16, etc.
            // maintenant The "data" subchunk contient la taille des data puis les data eux-mêmes
     
            char                    data[4];// "data"
            long                    Data_Size; // taille des data = NumSamples * NumChannels * BitsPerSample/8
            // ici commence les data dans le fichier wave
       };
    // fonction qui change la frequence et retourne le nombre de data 
    // atention : le nombre d'echantillons est = à nombre de data / BitsPerSample * 8 c'est à dire en 116b il y a 2X moins de d'échantillon
    // que de data. De plus si dans le header on trouve stereo, le nombre d'echantillon / canal
    // est encore la moitié du chiffre ci-dessus
    // stop ici si les waves: le sujet est illustrer acces fichier binaire
     
    // BitsPerSample = 8 ou 16
     
    long Set_Frequency_and_return_Ndata(Ansistring WAV, short fr)
    // attention a l'execution d'1 telle routine s'assurer que fr est une frequence
    // admise par la carte son en place.  c'est facile de les connaitre mais cela est un autre sujet.
       {
       long l;
       char C[255];
       FILE *f;
       stuct  Wave_File_Header HD;
       if ( ! FileExists(WAV))
           { ShowMwessage("fichier absent"); return -1;}
       for (short i=1; i<=WAV.Length(); i++) { C[i-1] = WAV[i]; C[i]='\0';}
       f = fopen(C,"rb");
       if ( f == NULL) 
          { showMessage(Impossible d'ouvrir en lecture " + WAV);  return -1;}
       if (filesize(fileno(f)) < sizeof(HD)) 
          {ShowMessage("même pas les  44 bytes du header! fichier DETRUIT"); fclose(f); unlink(C); return -1;}
       fread(&HD,1,44,f);
       fclose(f);
       l = HD.SampleRate;  // ancien data  
       HD.SampleRate = fr;
       HDByteRate=HD.ByteRate*fr/l;  // pour cet example d'un header --.wav
       f = fopen(C,"rb+");  // pas "wb" qui ecrase le file pour en creer un new
       // pas besoin de fseek ici car on pointe deja au debut
       fwrite(&HD,44,1,f);
       fclose(f);
       return HD.Data_Size;
       }
     
    // ( j'ai tapé ce tout petit code ici sans test d'une eventuelle erreur de frappe )

  5. #5
    Membre �prouv�

    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 163
    D�tails du profil
    Informations personnelles :
    �ge : 40
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 163
    Par d�faut
    Je pense aussi que le fichier binaire est le must.

    Pour une �volutivit� et une compatibilit� ascendante et descendante regarde du cot� des formats de fichier de type "CHUNK" comme le Wave (exemple � ne pas suivre car ce format est devenu un bordel monstre !).

    En gros tu as ton ent�te de fichier o� tu stockes ce dont tu as besoin. Puis dans ton fichier se suivent des blocs ou chunks.

    Chaque d�but de chunk est au format suivant :

    un identifiant sur 4 caract�res par exemple afin de savoir quel type de chunk on va lire
    imm�diatement apr�s l'identifiant le nombre d'octet de ce chunk afin de pouvoir facilement le sauter et passer au chunk suivant si on est pas capable de le lire (identifiant inconnu).

    Voila avec �a tu devrais avoir ton bonheur

  6. #6
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    Ok, merci!

    Je pensais qu'une telle solution existait d�j� ... Style un composant pour faire des archives. En plus c'est bien le fichier binaire mais � chaque fois que j'ai un TMemoryStream � sauvegarder il faut que je l'�crive dans un tableau de char puis seulement aller �crire dans le fichier ... pas tr�s rapide tout �a non?

    Cordialement,
    Rodrigue

  7. #7
    R�dacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    D�tails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Par d�faut
    Tu as la m�thode SaveToFile du MemoryStream non ?

  8. #8
    Membre �clair� Avatar de Rodrigue
    Inscrit en
    Ao�t 2002
    Messages
    487
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2002
    Messages : 487
    Par d�faut
    Merci Greybird mais je connais la m�thode SaveToFile... C'est vrai qu'une solution "simple" est possible.
    Il faudrait donc que je construise un TMemoryStream global dans lequel j'irais inscrire mes autres TMemoryStream que j'aurais segment�s par des rep�res (type de fichier + taille)...
    Je r�cup�re la taille de chacun de mes TMemoryStream via leur m�thode Size, le type de fichier est arbitraire mettons que je le code sur deux octets...
    Comment coller deux TMemoryStream ensemble ?

    Merci d'avance!
    Cordialement,
    Rodrigue

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Citation Envoy� par Rodrigue
    Comment coller deux TMemoryStream ensemble ?
    Tu peux envisager, tout simplement, d'�crire le contenu du flux A � la fin du flux B, puis de d�truire le flux A devenu inutile.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    // On va à la fin du flux B.
    B.Seek(0,soFromEnd);
    // Copie intégrale de A dans B.
    A.SaveToStream(B);
    // On peut détruire le flux A désormais.
    EDIT : Et une fois le TMemoryStream "complet" cr��, un bon p'tit coup de SaveToFile et ZOU ! Termin� ! ;-)
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  10. #10
    R�dacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    D�tails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Par d�faut
    Il y a aussi la m�thode CopyFrom je crois qui permet de copie les streams entre eux.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [XL-2007] Changement de format entre fichier sans extension -> Excel
    Par Floup dans le forum Macros et VBA Excel
    R�ponses: 6
    Dernier message: 20/02/2012, 15h36
  2. Quel SGBD correspond aux fichiers � extension .DAT
    Par jcpitaud dans le forum Autres SGBD
    R�ponses: 4
    Dernier message: 12/04/2006, 20h11
  3. [C / C++][Format de fichier] Le TIFF G4
    Par chronos dans le forum Windows
    R�ponses: 1
    Dernier message: 17/06/2005, 15h57
  4. [Format de Fichier] Recherche de site
    Par Pedro dans le forum Windows XP
    R�ponses: 5
    Dernier message: 12/04/2005, 16h11
  5. Quel format de fichier utiliser pour les maps ?
    Par fb57 dans le forum OpenGL
    R�ponses: 3
    Dernier message: 23/09/2004, 20h22

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