lecture et ecriture d'un fichier en binaire
Le
NicolasP

Bonjour,
Je suis tombé sur un os avec les fichiers : Je veux ouvrir un fichier en lecture et en écriture et en mode binaire.
Le but est d'écrire le contenu d'un fichier en binaire, de le relire pour calculer une checksum sur tout son contenu et enfin d'écrire cette checksum à la fin de ce même fichier.
Les modes rb, wb, r+ sont ok (mais c'est pas ce dont j'ai besoin).
Un mode r+b ne fait pas de binaire.
Impossible de trouver un mode qui fasse w + r + b.
Des idées ?
Nicolas
Je suis tombé sur un os avec les fichiers : Je veux ouvrir un fichier en lecture et en écriture et en mode binaire.
Le but est d'écrire le contenu d'un fichier en binaire, de le relire pour calculer une checksum sur tout son contenu et enfin d'écrire cette checksum à la fin de ce même fichier.
Les modes rb, wb, r+ sont ok (mais c'est pas ce dont j'ai besoin).
Un mode r+b ne fait pas de binaire.
Impossible de trouver un mode qui fasse w + r + b.
Des idées ?
Nicolas
Salut,
Ce n'est pas tant un problème de mode d'ouverture du fichier que des
méthdes utilisées pour écrire dans le fichier.
Regardes le module struct qui te permettra de lire/écrire des valeurs
binaires dans un fichier.
Exemple :
import struct
f = open ("fichier.dat", "w")
f.write (struct.pack ("iii", 10,20,30))
f.close()
Ce bout de code devrait te permettre d'écrite 3 entiers 32 bits dans le
fichier. Tu obtiendras un fichier de 12 octets.
Il y a peut-être d'autres solutions (ctypes par exemple) mais je n'ai
pas eu le temps d'utiliser.
Espérant que ça te convienne.
Non, ça ne marche pas.
Il faut que le fichier soit en mode binaire sinon à chaque fois qu'un octet de valeur 0x0A est écrit dans le fichier, un octet de valeur 0x0D est rajouté juste avant. L'utilisation de struct n'y change rien. f.write(struct.pack("B", 10)) n'écrit pas 0x0A dans le fichier mais 0x0D puis 0x0A (fichier en mode non binaire bien entendu).
Nicolas
Essaye alors open (fichier, "wb")
Il me semble que le "b" permet justement d'éviter sous Windows l'ajout
du CR (0x0D).
Sous Linux, je n'ai pas ce problème : il n'écrit ni LineFeed, ni CR.
Ce que je veux, c'est pouvoir écrire ET lire le fichier en binaire. wb ne permet que d'écrire, pas de lire.
Nicolas
"rb"
Pardon : "rb+" dans ton cas, si tu veux lire/écrire dans la même session.
Voir les manuel de fopen() pour plus d'explications.
Si tu dois te déplacer dans le fichier, regardes également fseek(),
ftell (), etc...
En fait, dans mon cas, 'wb+' est plus adapté (troncature du fichier à l'ouverture).
J'ai bien lu.
Mais en fait j'avais un bug par ailleurs qui faisait coincer la chose.
Justement, je pensais qu'en faisant une lecture de tout le fichier le pointeur d'écriture se retrouverait à la fin. Mais il semblerait que non. Avec un f.seek(0, 2), ça va beaucoup mieux.
Avec le code qui suit, ça marche :
f = open(file_name, 'w+b')
write_data(f)
# calcul et ecriture checksum
f.seek(0) # Pointeur en debut de fichier
d = f.read() # Ne deplace pas le pointeur d'écriture
c = checksum(d)
f.seek(0, 2) # Pointeur en fin de fichier
f.write(struct.pack('<L', c))
f.close()
Au final, j'ai créé une classe qui encapsule un objet file() et qui calcule la checksum à la volée.
Ca évite de relire le fichier.
Nicolas