OVH Cloud OVH Cloud

lecture de fichier binaire et stockage en mémoire - débutant

18 réponses
Avatar
mat
bonjour,
je voudrais lire un fichier binaire (un fichier jpg par exemple) et
enregistrer son contenu en mémoire pour ensuite faire un traitement dessus.
j'ai donc écrit le programme suivant :

#define BIN_BUFFER_SZ 8291*20 // définit la taille maximale de mon buffer

int main ( void ) {
FILE *fp;
char *buffer;
char *data;
size_t file_size;

fp = fopen("fichier.jpg", "rb");
if ( fp == NULL ) {
// fichier non trouvé
return 0;
}

buffer = (char *)malloc(BIN_BUFFER_SZ);
while(!feof(fp)) {
file_size = fread(buffer,1,BIN_BUFFER_SZ,fp);
}
fclose(fp);

// allocation de la taille exacte des données lues
data = (char *) malloc(file_size);
memcpy(data,buffer,file_size);


/// .... suite du triaitement sur data

return 1;
}


Problème :
- je ne récupére pas toutes les données qui se trouvent dans le buffer,
pourtant si je fais un :
fw = fopen("/tmp/out.jpg", "wb");
fwrite(data, file_size, 1, fw);
fclose(fw);
je récupére bien l'intégralité de mon fichier (un diff sur les deux
fichiers ne sort pas de différence).

Je précise que je suis un débutant en C, au cas où ça sautait pas aux
yeux :)

Je voudrais aussi savoir quels problèmes je peux avoir au niveau de la
mémoire. Est-ce qu'il faut que je libére le buffer immédiatement après
l'avoir copié avec un free(buffer) ? Je n'ai pas pu tester mais ne
serait-il pas mieux, au lieu de définir la variable BIN_BUFFER_SZ, de
récupérer la taille du fichier par fstat() (ou équivalent) et de faire
le malloc ensuite ?

Merci de vos lumiéres.

mat

8 réponses

1 2
Avatar
mat
DINH Viêt Hoà wrote:


salut,
ma sortie peut effectivement le faire, en faisant un cat test.jpg le
contenu s'affiche correctement. avec quelles fonctions puis-je le faire
en C ?



pas sous forme d'image. Mais un ensemble de données éventuellement
incompréhensible, sauf si tu sais lire dans la matrice.



pas encore trouvé les pilules c'est pour ça ...


la sortie standard ne peut afficher que du texte.



donc pas moyen d'afficher les données qui se trouvent dans le buffer? je
suis obligé de les écrire dans un fichier pour savoir si elles sont bien
stockées dans le buffer?

merci.

mat


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', mat wrote:

size_t _get_file_size ( fp )
FILE *fp;


Huh! Dans quel bouquin as-tu appris ce vieux style? Depuis 1989, on
écrit:

size_t _get_file_size (FILE *fp)


en fait j'ai pas de bouquin, j'ai vu ce style dans le code source d'un


Grave erreur.

ami et il m'a plu.


C'est insuffisant. Il faut des références.

- est-il possible à partir d'un pointeur de connaître la taille mémoire
qu'il occupe?


Non. Puisque c'est toit qui a alloué, tu connais la taille. Il suffit de la
stocker dans un endroit adéquate.

- est-il possible d'imprimer le contenu de p_buffer sur la sortie
standard pour que le contenu du fichier s'affiche à l'écran?


Oui, sous forme numérique (héxadécimale), par exemple.

Une boucle avec i de 0 à la taille-1 qui fait:

printf (%02X ", (unsigned) p_buffer[i]);

Il faut aussi gérer une mise en page correcte, genre 16 valeurs par ligne par
exemple... Dans les archives, chercher un de mes posts avec 'xdump'

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/



Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', DINH Viêt Hoà wrote:

- est-il possible d'imprimer le contenu de p_buffer sur la sortie
standard pour que le contenu du fichier s'affiche à l'écran?


Tout à fait, sauf si éventuellement ta sortie standard ne sait pas
afficher tous les caractères contenus dans le fichier.


Pas d'accord. Certains caractères (n, r, t a etc.) seront probablement
interprétés (stdout est ouvert en mode texte). D'autres pourront avoir un
glyphe identique, et on ne saura pas les différencier. Enfin les codes de
contrôle (en ASCII, 0-31, par exemple) n'ont pas forcément de glyphes
associés.

C'est pourquoi, j'ai proposé au P.O. une transcription numérique (hexa, par
exemple) comme fait n'importe quel dumper. Rien de nouveau.

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', mat wrote:

ma sortie peut effectivement le faire, en faisant un cat test.jpg le
contenu s'affiche correctement.


Qu'est-ce que tu appelles 'correctement? Tu vois l'image? Si c'est le cas,
ton système dispose de fonctions très avancées sachant gérer les modes texte
et graphique en même temps.

Je n'ai vu ça qu'en BASIC HP sur une station HP 9000.

avec quelles fonctions puis-je le faire
en C ?


Si tu cherches un affichage graphique, le C standard ne sait pas faire. Il
faut des fonctions système ou des bibliohèques spécialisées.

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', mat wrote:

je voudrais savoir s'il est possible de renvoyer la taille occupée en
mémoire par le pointeur ptr ?


Non.

(je sais que je la connais car je l'alloue
mais c'est pour savoir si c'est possible de la savoir à partir du
pointeur).


Puisque tu la connais, à toi de la stocker. Le couple adresse, longueur est
un idiome très courant pour gérer un buffer dynamique.

typedef struct
{
size_t size;
void *address;
}
buffer_s;

et enfin je voudrais savoir comment est-ce que je peux faire
(si possible) pour imprimer sur la sortie standard le contenu du
pointeur, ce qui dans mon cas imprimera le contenu du fichier binaire
que j'ai lu.


Il faut transcrire les valeurs binaires (0-255) en nombre lisible (par
exemple hexa) bute par byte :

02 45 4A 2F etc.

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
mat
Emmanuel Delahaye wrote:

ami et il m'a plu.



C'est insuffisant. Il faut des références.



mon ami est une référence ... ok j'arrête.
je me procurerais les bouquins conseillés dans la faq.



- est-il possible à partir d'un pointeur de connaître la taille mémoire
qu'il occupe?



Non. Puisque c'est toit qui a alloué, tu connais la taille. Il suffit de la
stocker dans un endroit adéquate.


oui, c'était juste par curiosité pour savoir si c'était possible de la
retrouver.




- est-il possible d'imprimer le contenu de p_buffer sur la sortie
standard pour que le contenu du fichier s'affiche à l'écran?



Oui, sous forme numérique (héxadécimale), par exemple.

Une boucle avec i de 0 à la taille-1 qui fait:

printf (%02X ", (unsigned) p_buffer[i]);

Il faut aussi gérer une mise en page correcte, genre 16 valeurs par ligne par
exemple... Dans les archives, chercher un de mes posts avec 'xdump'



ok merci, c'était ce que je voulais savoir.
par contre groups.google.com ne trouve pas de post avec les mots-clés
xdump delahaye.

merci pour tout!

mat


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', mat wrote:

par contre groups.google.com ne trouve pas de post avec les mots-clés
xdump delahaye.


Normal, c'étais 'xdmp'. Désolé.

Message-ID:

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Bertrand Mollinier Toublet
mat wrote:
Emmanuel Delahaye wrote:
In 'fr.comp.lang.c', mat wrote:

size_t _get_file_size ( fp )
FILE *fp;


Huh! Dans quel bouquin as-tu appris ce vieux style? Depuis 1989, on
écrit:

size_t _get_file_size (FILE *fp)


en fait j'ai pas de bouquin, j'ai vu ce style dans le code source d'un
ami et il m'a plu.

Le probleme, c'est que les deux styles ne sont pas equivalents. Dans le

style "qui te plait", il y a des petites subtilites qui font que le
style moderne est tres recommande. En particulier, avec le vieux style,
tu abandonnes un certain nombre de verifications de la part de ton
compilateur.

--
Bertrand Mollinier Toublet
"Uno no se muere cuando debe, sino cuando puede"
-- Cor. Aureliano Buendia



1 2