Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

lecture et ecriture d'un fichier en binaire

7 réponses
Avatar
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

7 réponses

Avatar
Alain BARTHE
NicolasP a écrit :
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



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.
Avatar
NicolasP
Alain BARTHE a écrit :
NicolasP a écrit :
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



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
Avatar
Alain BARTHE
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
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



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.
Avatar
NicolasP
Alain BARTHE a écrit :
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
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



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
Avatar
Alain BARTHE
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
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



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"
Avatar
Alain BARTHE
Alain BARTHE a écrit :
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
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



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...
Avatar
NicolasP
Alain BARTHE a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
Alain BARTHE a écrit :
NicolasP a écrit :
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



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.



En fait, dans mon cas, 'wb+' est plus adapté (troncature du fichier à l'ouverture).


Voir les manuel de fopen() pour plus d'explications.



J'ai bien lu.
Mais en fait j'avais un bug par ailleurs qui faisait coincer la chose.


Si tu dois te déplacer dans le fichier, regardes également fseek(),
ftell (), etc...


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