Lecture-écriture de fichier octet par octet
gnugo
-
gnugo -
gnugo -
Bonjour,
Je cherche à lire un fichier octet par octet en C, et mon programme semble fonctionner sur des fichiers texte, mais pas sur des fichiers "binaires".
Et je n'arrive pas à comprendre pourquoi alors je sollicite votre aide:
(je travaille sous Windows avec code::blocks et le compilateur par défaut livré avec)
exemple avec un fichier .swf de 4Mo : il me fait un fichier de 900ko...
il s'est arrêté avant d'écrire un octet valant "1a" en hexadécimal (?) ....
Pourriez-vous me dire ce qui cloche?
Merci :)
Je cherche à lire un fichier octet par octet en C, et mon programme semble fonctionner sur des fichiers texte, mais pas sur des fichiers "binaires".
Et je n'arrive pas à comprendre pourquoi alors je sollicite votre aide:
(je travaille sous Windows avec code::blocks et le compilateur par défaut livré avec)
#include <windows.h>
#include <stdio.h>
int main(int nb, char **arg)
{
FILE *f;
FILE *f2;
f=fopen(arg[1],"r");
f2=fopen("lala","w");
char c;
while (fread(&c,1,1,f)) fwrite(&c,1,1,f2);
fclose(f);
fclose(f2);
}
exemple avec un fichier .swf de 4Mo : il me fait un fichier de 900ko...
il s'est arrêté avant d'écrire un octet valant "1a" en hexadécimal (?) ....
Pourriez-vous me dire ce qui cloche?
Merci :)
A voir également:
- Lecture-écriture de fichier octet par octet
- Fichier bin - Guide
- Fichier epub - Guide
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier .dat - Guide
2 réponses
Salut gnugo,
Hxyp a raison, il faut lire en binaire.
Le caractère dont la valeur hexadécimale est 0x1a correspond à Ctrl-Z.
Sous Windows, Ctrl-Z est équivalent de EOF (End Of File).
Raymond Chen (un développeur qui est chez Microsoft depuis une vingtaine d'années), sur son blog, explique que l'origine de cette convention vient de la façon dont CP/M estimait la taille des fichiers "à la louche" par secteurs, et que remplir l'espace non utilisé de Ctrl-Z était la seule façon de s'assurer que lors de la lecture du fichier, on s'arrêterait au premier Ctrl-Z rencontré, puisque c'était la seule manière de savoir que le secteur n'était pas complètement utilisé.
https://docs.microsoft.com/en-us/archive/blogs/
Du coup, on est très contents d'avoir des systèmes Windows dans lesquels on peut lire des fichiers écrits sur des supports gérés par CP/M ... alors que vraisemblablement, plus aucune machine actuelle ne peut lire les supports de l'époque, mais c'est un détail :-)
Hormis ce point d'histoire du pourquoi du comment, dans la mesure où ton fichier est un fichier .swf et que c'est donc un fichier binaire, et non un fichier ASCII, c'est toujours une meilleure idée de le lire en binaire.
D'ailleurs, sous Linux, je pense que tu aurais le même effet en lisant un fichier contenant cette fois Ctrl-D, qui équivaut à EOF sous Linux (à tester, pour les longues soirées d'hivers).
Dal
Hxyp a raison, il faut lire en binaire.
Le caractère dont la valeur hexadécimale est 0x1a correspond à Ctrl-Z.
Sous Windows, Ctrl-Z est équivalent de EOF (End Of File).
Raymond Chen (un développeur qui est chez Microsoft depuis une vingtaine d'années), sur son blog, explique que l'origine de cette convention vient de la façon dont CP/M estimait la taille des fichiers "à la louche" par secteurs, et que remplir l'espace non utilisé de Ctrl-Z était la seule façon de s'assurer que lors de la lecture du fichier, on s'arrêterait au premier Ctrl-Z rencontré, puisque c'était la seule manière de savoir que le secteur n'était pas complètement utilisé.
https://docs.microsoft.com/en-us/archive/blogs/
Du coup, on est très contents d'avoir des systèmes Windows dans lesquels on peut lire des fichiers écrits sur des supports gérés par CP/M ... alors que vraisemblablement, plus aucune machine actuelle ne peut lire les supports de l'époque, mais c'est un détail :-)
Hormis ce point d'histoire du pourquoi du comment, dans la mesure où ton fichier est un fichier .swf et que c'est donc un fichier binaire, et non un fichier ASCII, c'est toujours une meilleure idée de le lire en binaire.
D'ailleurs, sous Linux, je pense que tu aurais le même effet en lisant un fichier contenant cette fois Ctrl-D, qui équivaut à EOF sous Linux (à tester, pour les longues soirées d'hivers).
Dal
Merci beaucoup pour ces explications détaillées! C'est toujours on à savoir!
Après, je ne comprends pas vraiment pourquoi il y a ce "mode binaire" pour lire/écrire un fichier.
Je pensais que la taille du fichier était inscrite quelque part dans l'inode/le filesystem et donc qu'on lisait jusqu'à cette position fixe qui signifiait la fin du fichier. Peu importe alors le type du fichier.
S'arrêter lorsqu'on trouve un caractère particulier est assez étrange comme façon de procéder...à moins de ne pas avoir le choix.
Pour savoir si on est à la fin d'un fichier, on n'utilise pas sa taille ?
Après, je ne comprends pas vraiment pourquoi il y a ce "mode binaire" pour lire/écrire un fichier.
Je pensais que la taille du fichier était inscrite quelque part dans l'inode/le filesystem et donc qu'on lisait jusqu'à cette position fixe qui signifiait la fin du fichier. Peu importe alors le type du fichier.
S'arrêter lorsqu'on trouve un caractère particulier est assez étrange comme façon de procéder...à moins de ne pas avoir le choix.
Pour savoir si on est à la fin d'un fichier, on n'utilise pas sa taille ?
Petite correction, je pense que cela doit être EOT (End Of Text), plutôt que EOF. Peut être cela répond il déjà à ta question ?
A la limite, le texte, dans un fichier pourrait se terminer à un certain endroit, sans que cela signifie que le fichier s'est terminé (il peut y avoir des données binaires à la suite, par exemple...).
La façon dont on détermine la taille d'un fichier dans un système de fichiers est dépendante du système de fichiers et ne concerne pas le C.
Le mode texte est très pratique pour lire du texte.
Tu peux, par exemple, lire ton fichier texte ligne par ligne avec fgets. Lorsque fgets rencontre le caractère "newline" \n la fonction s'arrête de lire la ligne (après avoir capturé \n), et tu peux lire la ligne suivante.
Le mode texte interprète les caractères qu'il trouve dans le fichier lu comme du texte, y compris les codes spéciaux et caractères de contrôle, qui sont des caractères non imprimables, mais qui peuvent avoir une signification ou une action particulière en ASCII. Par exemple, le caractère 0x07 (Bell), lorsqu'il est affiché génère un bip sur le haut parleur de l'ordinateur, ou le caractère 0x04 (EOT, ou 0x1a sous Windows, donc), lorsqu'il est lu, signifie la fin du texte.
https://www.commentcamarche.net/informatique/technologies/1589-code-ascii/
Ce n'est pas le cas du mode binaire, qui ne va tenir aucun compte des caractères de contrôle, car il ne lit pas de l'ASCII.
S'il y a deux modes, il y a plein de bonnes raisons.
Dal
A la limite, le texte, dans un fichier pourrait se terminer à un certain endroit, sans que cela signifie que le fichier s'est terminé (il peut y avoir des données binaires à la suite, par exemple...).
La façon dont on détermine la taille d'un fichier dans un système de fichiers est dépendante du système de fichiers et ne concerne pas le C.
Le mode texte est très pratique pour lire du texte.
Tu peux, par exemple, lire ton fichier texte ligne par ligne avec fgets. Lorsque fgets rencontre le caractère "newline" \n la fonction s'arrête de lire la ligne (après avoir capturé \n), et tu peux lire la ligne suivante.
Le mode texte interprète les caractères qu'il trouve dans le fichier lu comme du texte, y compris les codes spéciaux et caractères de contrôle, qui sont des caractères non imprimables, mais qui peuvent avoir une signification ou une action particulière en ASCII. Par exemple, le caractère 0x07 (Bell), lorsqu'il est affiché génère un bip sur le haut parleur de l'ordinateur, ou le caractère 0x04 (EOT, ou 0x1a sous Windows, donc), lorsqu'il est lu, signifie la fin du texte.
https://www.commentcamarche.net/informatique/technologies/1589-code-ascii/
Ce n'est pas le cas du mode binaire, qui ne va tenir aucun compte des caractères de contrôle, car il ne lit pas de l'ASCII.
S'il y a deux modes, il y a plein de bonnes raisons.
Dal
vraiment bizarre. Sans le b il fait quoi alors ?
Je teste demain. Merci !