PDA

Voir la version complète : C++ et fichier Binaire


Franz
17/04/2005, 19h57
bonjour à tous,

dans le prog que je suis en train de faire, j'ai inclus une classe de Log qui enregistre dans un buffer tout ce qui se passe dans le programme.
ensuite a la fin de mon prog, j'ecris tout ce que le buffer contient dans un fichier BINAIRE via la fonction fwrite.

fwrite(Buffer , 1 , GetSize() , pFile);
avec Getsize() la fonction renvoyant la taille de mon Buffer.

j'ai donc une structure qui contient les infos relatives au Log :


//header de chaque item dans le log
struct LOGITEMHEADER
{
DWORD time; //temps ou l'item a ete enregistre dans le log
char name[NAME_SIZE]; //nom du module qui a enregistre l'item
LOGTYPE type; //type d'enregistrement (cf struct LOGTYPE)
DWORD size; //taille en BYTE de l'item loggue (header non compris)
};


mais apres je n'arrive pas a recuperer toutes les infos ecris dans mon fichier :
pourtant j'ai essayer avec fread,et ifstream .
sans compter que je suis aller ratisser la MSDN :) et google.

donc si vraiment vous savez comment faire je suis preneur :p

merci
Franz

tyrion42
17/04/2005, 20h09
Il nous faut la structure de LOGTYPE pour avoir plus d'information sur ton problème

Loulou
17/04/2005, 20h23
Plusieurs remarques :

- N'utilise pas ces vieilles fonctions du C. Le C++ a tout ce qu'il faut via les fstream.

- Quelle est cette structure LOGTYPE ? Buffer est un tableau de LOGITEMHEADER ?

- Montre nous ton code de lecture, puisque c'est ça qui pose problème.

- Au pire si tu manipules des trucs un peu compliqués, il existe des bibliothèques de sérialisation (boost::serialization (http://www.boost.org/libs/serialization/doc/index.html) ). Mais peut-être que ce serait sortir la grosse artillerie pour ton problème.

- Pense à utiliser les balises CODE (tu peux éditer ton message précédent pour les ajouter), ça rend le code beaucoup plus lisible.

Franz
17/04/2005, 22h29
alors voici mon enum LOGTYPE :

enum LOGTYPE
{
DL_TXT = 0, // texte
DL_BMP, // image venant du traitement video
DL_EVENT // cf struct LOGEVENT
};

apres dans mon programme je peux logguer par exemple une chaine de caractere via la fonction LogString(char *module, char *message) :

LOGITEMHEADER item;

item.time = timer->GetTimeFromStart();
strncpy(item.name, module, NAME_SIZE);
item.type = DL_TXT;
item.size = (DWORD)strlen(message);

ici on stocke les infos dans "item", puis apres on copie le tout dans Top
->definit par BYTE* Top (et BYTE c'est un unsigned char)


on copie le header
memcpy(Top, &item, sizeof(LOGITEMHEADER));
Top += sizeof(LOGITEMHEADER);

//puis on copie les donnees
memcpy(Top, message, item.size);
Top += item.size;



enfin lorsque l'on ferme l'application on copy tout ce qu'il ya dans le buffer dans un fichier binaire.

pFile = fopen(path , "wb");

if(pFile)
fwrite(Top , 1 , GetSize() , pFile);

fclose(pFile);

puis apres moi dans un autre programme j'essaye de lire mon fichier binaire mais c'est a partir de la que ca coince...
si vous avez une (voire des) idees :)

merci encore

Corkus
18/04/2005, 02h09
Utilise plutot les méthodes comme fout() du C++.
Ensuite avec fout et fin n'oublie pas de les déclarer avec ios::binary( je ne sais pas comment on fait avec fopen, etc...).
Va voir aussi sur Developpez.com (http://c.developpez.com/faq/cpp/?page=fichiers) pour avoir plus de renseignement sur la manipulation des fichiers.

Finalement si tu peux nous donnez ton code de lecture pour voir si ya pas un problème plutot là ;)

Franz
18/04/2005, 11h19
voila comment je procede pour la lecture du fichier de log :

LOGITEMHEADER* log;
log =new LOGITEMHEADER;
ifstream fin;
fin.open("Log2.log",ios_base::binary);
fin.read((char*)log,sizeof(LOGITEMHEADER));
cout <<log->name;
cout<<"\t"<<log->time;


normalement j'ai a ce stade les infos relatives au log : l'heure, la classe qui a loguéé...

apres il faut que je recupere le message logué :

BYTE* buff;
buff = new BYTE[1024];
fin.read((char*)buff,log->size);
cout<<" "<<buff;


si vous voyez ou ca cloche...
merci a tous

Corkus
18/04/2005, 13h30
Pour l'écriture, pourquoi tu n'inscrit pas directement ta struc dans le fichier comme ceci:


LOGITEMHEADER item;

//Tu remplit ton item

ofstream fichier("nom.log",ios::binary);

fichier.write((char*) &item, sizeof item); //Et la tu met item dans le fichier


Au lieu de passer par memcpy

Franz
18/04/2005, 16h59
salut ,
alors moi je trouve ca tres bizarre : j'ai change ma fonction d'ecriture en remplacant le fwrite par un "ofstream fout.write(...)"
et maintenant tout fonctionne parfaitement :00000014:

l'essentiel c'est que ca marche mais j'ai quand meme pas tout compris...

sinon une question pour toi Corkus :
toi tu as mis :
fichier.write((char*) &item, sizeof item)

or moi j'ai mis
fichier.write((char*) &item, sizeof(LOGITEMHEADER))

est ce que ca change quelque chose ou pas ?

merci bcp

Franz

Corkus
18/04/2005, 21h53
En fait non:D

Car l'espace alloué est toujours le même. Tu as juste a faire sizeof() sur les 2 et tu verra que la taille sera la même

Si tu as d'autre question gène toi pas.

nikau6
06/03/2008, 17h54
C'est normale que ça ne marchait pas avant.Avec ifstream il faut utiliser ofstream.

Il existe une autre facon d'ecrire sur des fichiers avec ifstream et ofstream.Tu utilise les opérateurs de décalage de bits (<< et >>)comme avec cout et cin.

exemple:

#include<fstream>
#include<iostream>

using namespace std;

int main(void)
{


ofstream fichierOut("fichier.txt",ios::binary);//Fichier en écriture.Si il n'existe
//pas,il est crée.(ios::binary
// pour ecrires en binaire)
fichierOut << "Texte ecrit dans fichier.txt" ;
fichierOut.close();

ifstream fichierIn("fichier.txt",ios::binary);//la même chose pour la lecture.

string tampon;

fichierIn >> tampon;//Lit le fichier et envoie les données dans tampon

cout << tampon;

fichierIn.close();

return 0;
}

La différence avec cette facon et .write et .read c'est qu'avec .write et .read
les données sont lues et écrites éxactements dans l'état dans lequel elle ce trouve.Aucune convertions n'est éxecutée.