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 Discussion :

[Gestion de fichiers] Lecture octet par octet


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut [Gestion de fichiers] Lecture octet par octet
    J'ai écris une fonction qui me permet de lire un fichier et d'en retourner le contenu dans une chaines de caractères.

    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
    static char *pReadFile(const char *filename)
    {
    	char *buffer = NULL;
    	FILE *fSrc = fopen(filename, "r");
    	unsigned int	poc=0;
     
    	if (fSrc != NULL)
    	{
    		fseek(fSrc, 0, SEEK_END);       // aller en fin
    		unsigned long size = ftell(fSrc);             // lire la taille
    		/* ne pas depasser ce que peut contenir un size_t ... */
    		if (size < (size_t) - 1)
    		{
    			rewind(fSrc);    // rétablir la position
     
    			/* allouer le bloc + une place pour le 0 */
    			buffer = malloc(size + 1);
    			if (buffer != NULL)
    			{
    				int ok = 0;
    				/* lire le ficher (in one glup...) */
    				poc = fread(buffer, 1,size, fSrc);
     
    				if (ferror(fSrc)) {
    					Log(3, "FILE_GET", "Erreur de lecture du fichier '%s' ", filename);
    					fclose(fSrc);
    				}
     
    				Log(1, "FILE_GET", "File siez : '%d' (octets)", poc);		
     
    				if (poc == size)
    				{
    					/* ajouter le 0 final */
    					buffer[size] = 0;
    					ok = 1;
    				}
     
    				if (!ok)
    				{
    					Log(3, "FILE_GET", "Erreur sur taille de fichier attendu : %d -> %d", poc, size);
    					/* en cas d'erreur de lecture, liberer le bloc ... */
    					free (buffer), buffer = NULL;
    				}
    			}
    		}
    		fclose(fSrc), fSrc = NULL;
    	}
    	else
    	{
    		Log(3, "FILE_GET", "Impossible d'ouvrir le fichier '%s' ", filename);
    	}
     
    	return buffer;
    }
    La fonction tourne bien, sauf sur certains fichiers, qui contiennent des octets "vide" ('0'), équivalent au "end of file".

    Exemple de fichier (affiché en hexadécimal):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    00 52 F1 00 F8 F7 F3 F0 F0 F8 F8 F3 F0 F0 F0 F0
    F5 F1 F5 F5 F8 F0 F6 F0 F7 F2 F4 F0 F0 F0 F1 F0
    F2 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0
    F0 F0 F1 F4 F4 F8 F0 F3 F0 F6 F0 F7 F2 F5 F8 F7
    F2 F1 F1 F0 F6 F0 F7 F2 F4 F2 F2 F3 F4 F0 F0 F0
    F0 F0 00 FD F3 F0 F0 F1 F1 5F E0 00 00 F4 F4 F8
    F0 F3 F0 F6 F0 F7 F2 F5 F8 F7 F2 F1 F1 F3 F1 F1
    F3 F1 F1 F1 F8 F7 F3 F9 F0 F1 F3 F7 F4 F6 F1 F1
    Je suis newbie en C.

    Comment lire ce genre de fichier, comprennant des octets '0' ?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    \0 n'est pas end of file, c'est juste une fin de chaîne.
    Le caractère "fin de fichier texte", c'est Ctrl-Z sous DOS/Windows, Ctrl-D sous Unixoïde.

    Et je te conseillerait de lire le fichier en mode binaire plutôt qu'en mode texte (ajoute le caractère 'b' au second paramètre de fopen()).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut
    ce qui veut dire que ma fonction ne devrait pas retourner chaine de caractères mais d'octet ?

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ta fonction devrait retourner un tableau d'octets et sa longueur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par kendras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FILE *fSrc = fopen(filename, "r");
    Si tu veux lire des fichiers binaires, il faut les ouvrir avec rb, sinon tu risques d'avoir des problèmes avec les fins de lignes avec Windows et d'autres problèmes avec des plateformes plus exotiques.

    Citation Envoyé par Médinoc
    Le caractère "fin de fichier texte", c'est Ctrl-Z sous DOS/Windows, Ctrl-D sous Unixoïde.
    Il n'y a pas de caractère fin de ligne sous Unix. Le gestionnaire de terminal interprète (généralement, on peut spécifier ce qu'on veut avec stty) CTRL-D comme la nécessité de transmettre le tampon à une application qui serait en attende d'I/O, et les applications interprètent une demande de lecture bloquante retournant 0 bytes comme la fin de fichier.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par kendras
    J'ai écris une fonction qui me permet de lire un fichier et d'en retourner le contenu dans une chaines de caractères.
    <...>
    Comment lire ce genre de fichier, comprennant des octets '0' ?
    Le fichier semble être un fichier binaire (c'est à dire n'importe quoi, mais pas 'texte').

    Pour lire un tel fichier, il fait connaitre sa structure, sinon, on se contente de la lecture octet par octet, mais on ne sait pas quoi en faire, à part les afficher comme le fait l'éditeur hexadécimal que tu as montré.
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut
    En fait, le fichier contient différentes données dans diffférents formats (ASCII, Binaire, et EBCDIC).

    Je ne souhaite pas traité le contenu du fichier, mais simplement le lire pour le transférer à une file MQ.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FILE *fSrc = fopen(filename, "rb");
    Ca ne fonctionne pas mieux qu'avant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    poc = fread(buffer, 1,size, fSrc);
    printf("\n %s\n", buffer);
    Il ne m'affiche rien... pourtant mon fichier fait plus de 5000 octets

  8. #8
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Citation Envoyé par kendras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    poc = fread(buffer, 1,size, fSrc);
    printf("\n %s\n", buffer);
    Il ne m'affiche rien... pourtant mon fichier fait plus de 5000 octets
    Ce n'est pas du texte que tu lis, mais des données binaires. Or le format "%s" est fait pour afficher une chaîne de caractères. C'est donc normal que ça ne fonctionne pas.
    Pourtant, dans ton buffer, tu as les données lues dans le fichier. Il te reste à les transférer dans ta file MQ.
    [alkama] quelqu'un est allé voir la guerre des mondes?
    [@Chrisman] j'espère pour spielberg
    --- bashfr.org

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par kendras
    En fait, le fichier contient différentes données dans diffférents formats (ASCII, Binaire, et EBCDIC).

    Je ne souhaite pas traité le contenu du fichier, mais simplement le lire pour le transférer à une file MQ.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    poc = fread(buffer, 1,size, fSrc);
    printf("\n %s\n", buffer);
    Il ne m'affiche rien... pourtant mon fichier fait plus de 5000 octets
    Les données ne sont pas du texte mais des octets dont seul celui qui a créé le fichier connait la signification. Tu ne peux pas utiliser printf() si les données ne sont pas du texte pur.

    Si tu ne veux que transférer le bloc de données (adresse, longueur), par de problème, mais ne cherche à l'afficher comme ça.

    Sinon, ce que je fais dans ces cas là, et à titre de mise au point, c'est d'utiliser une fonction de mon cru qui s'appelle SYS_dump (void const *p, size_t size) qui reçoit une adresse et une longueur, et qui affiche les octets sous forme de valeur hexa avec un champ texte pour ce qui est imprimable...

    http://emmanuel-delahaye.developpez.com/clib.htm
    Module SYS
    Pas de Wi-Fi à la maison : CPL

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut
    Et comment puis-je faire pour récupérer la taille de mon buffer ?
    strlen ne fonctionne pas (à cause de mes octets à 0 qui fausse le résultat), et sizeof me retourne 4 alors que mon fichier test fait 5938 octets

  11. #11
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par kendras
    Et comment puis-je faire pour récupérer la taille de mon buffer ?
    strlen ne fonctionne pas (à cause de mes octets à 0 qui fausse le résultat), et sizeof me retourne 4 alors que mon fichier test fait 5938 octets
    A ton avis, la variable poc contient quoi, voir la page man en cas de doutes...

    Jc

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut
    oui, je sais, mais je voulais savoir s'il n'y avait pas moyen de récupérer la taille autrement.... je suis dans une fonction qui me retourne mon buffer.

    La variable poc devient donc initulisable car hors context...
    J'aimerai éviter d'avoir à la sortir de mon context (à savoir de ma fonction)

  13. #13
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Citation Envoyé par kendras
    Et comment puis-je faire pour récupérer la taille de mon buffer ?
    strlen ne fonctionne pas (à cause de mes octets à 0 qui fausse le résultat), et sizeof me retourne 4 alors que mon fichier test fait 5938 octets
    strlen n'est utilisable que sur des chaînes de caractères (ce qui n'est pas le cas ici, puisque tes données sont BINAIRES).
    sizeof renvoie la taille de la variable, qui est ici un pointeur (soit 4 octets).
    Le seul moyen de savoir combien d'octets ont été lus est de récupérer l'information retournée par ta fonction de lecture fread.
    [alkama] quelqu'un est allé voir la guerre des mondes?
    [@Chrisman] j'espère pour spielberg
    --- bashfr.org

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut
    Oki, merci.

    Bon bah on va faire comme ça alors

    Big Thankx les gars

  15. #15
    Membre éclairé Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Points : 862
    Points
    862
    Par défaut
    sizeof me retourne 4 alors que mon fichier test fait 5938 octets
    Surement que tu fais sizeof(buffer) et buffer pointe sur l'adresse du premier élément de ton tableau, donc sizeof retourne la taille de ton ponteur, soit généralement 4 octets.

    A ton avis, la variable poc contient quoi, voir la page man en cas de doutes...
    Attention psoc ne contiendra pas le nombre d'octets mais le nombre d'éléments de x octets. Alors il faut bien jouer avec les paramètres de fread().

  16. #16
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par kendras
    Et comment puis-je faire pour récupérer la taille de mon buffer ?
    strlen ne fonctionne pas (à cause de mes octets à 0 qui fausse le résultat), et sizeof me retourne 4 alors que mon fichier test fait 5938 octets
    Tu peux faire une mesure avec fseek()/ftell(), mais ce n'est pas forcément utile.

    Tu peux aussi charger le fichier par blocs avec fread() (dans certaines conditions, fread() retourne le nombre d'octets chargés), et éventuellement chainer ou assembler les blocs...

    Il faut apprendre à bien utiliser fread(). Bien lire la doc.
    Pas de Wi-Fi à la maison : CPL

  17. #17
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut
    Citation Envoyé par homeostasie
    Attention psoc ne contiendra pas le nombre d'octets mais le nombre d'éléments de x octets. Alors il faut bien jouer avec les paramètres de fread().
    bien vu.
    Bon bah je vais regarder le manuel.

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 331
    Points : 180
    Points
    180
    Par défaut
    * cogite cogite *

    size_t fread (void *ptr, size_t size, size_t nmemb, FILE *stream);
    La fonction fread lit nmemb éléments de données, chacun d'eux représentant size octets de long, depuis le flux pointé par stream, et les stocke à l'emplacement pointé par ptr.

    fread et fwrite renvoient le nombre d'éléments correctement lus ou écrits (et non pas le nombre d'octets). Si une erreur se produit, ou si la fin du fichier est atteinte en lecture, le nombre renvoyé est plus petit que nmemb et peut même être nul.

    Donc techniquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned long size = ftell(fSrc);
    poc = fread(buffer, 1,size, fSrc);
    Je récupère ma taille en octet et je lis mon fichier en un seul jet.
    Donc à priori, je suis OK...

  19. #19
    Membre éprouvé Avatar de zooro
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2006
    Messages : 921
    Points : 1 260
    Points
    1 260
    Par défaut
    Citation Envoyé par kendras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned long size = ftell(fSrc);
    poc = fread(buffer, 1,size, fSrc);
    Je récupère ma taille en octet et je lis mon fichier en un seul jet.
    Donc à priori, je suis OK...
    Il faut bien sûr que buffer soit correctement dimensionné, et que tu vérifies que tu as bien lu poc=1 éléments.
    [alkama] quelqu'un est allé voir la guerre des mondes?
    [@Chrisman] j'espère pour spielberg
    --- bashfr.org

  20. #20
    Membre éclairé Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Points : 862
    Points
    862
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    poc = fread(buffer, 1,size, fSrc);
    Je récupère ma taille en octet et je lis mon fichier en un seul jet.
    Donc à priori, je suis OK...
    Vérifie la valeur retournée dans poc si ca corresponds au nombre d'octets que tu désirais lire.

    Il faut bien sûr que buffer soit correctement dimensionné, et que tu vérifies que tu as bien lu poc=1 éléments.
    Non dans ce cas, poc = size éléments de 1 octets, c'est à dire égale au nombre d'octets lus.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Lecture d'un fichier octet par octet
    Par oranoutan dans le forum C
    Réponses: 2
    Dernier message: 12/07/2008, 16h30
  2. Lecture d'un fichier .wav octet par octet
    Par DevVB dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 27/07/2007, 12h10
  3. [Java 1.4] : lecture d'un fichier octet par octet
    Par Thi0123 dans le forum Entrée/Sortie
    Réponses: 10
    Dernier message: 08/06/2007, 21h29
  4. Lecture d'un fichier octet par octet
    Par Yux dans le forum C
    Réponses: 7
    Dernier message: 31/10/2005, 22h58
  5. Lecture d'un fichier octet par octet
    Par PopKoRn...X_x dans le forum C++
    Réponses: 10
    Dernier message: 01/07/2005, 19h09

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