L'écriture des données binaires dans un fichier en Python
Je suis en train d'écrire des données (texte, de données à virgule flottante) pour un fichier en binaire, ce qui est d'être lu par un autre programme plus tard. Le problème est que ce programme (dans Fort95) est incroyablement particulier; chaque octet doit être exactement au bon endroit pour que le fichier soit lu correctement. J'ai essayé à l'aide d'Octets objets et .encode() pour écrire, mais je n'ai pas eu beaucoup de chance (je peux dire de la taille du fichier que c'est de l'écriture extra-octets de données). Certains code que j'ai essayé:
mgcnmbr='42'
bts=bytes(mgcnmbr)
test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(bts)
test_file.close()
J'ai aussi essayé:
mgcnmbr='42'
bts=mgcnmbr.encode(utf_32_le)
test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(bts)
test_file.close()
Pour préciser, ce que j'ai besoin est le nombre entier de valeur 42, écrit comme un 4 octet binaire. Ensuite, je voudrais écrire les nombres de 1 et de 0 à 4 octets binaires. À ce stade, je devrais avoir exactement 12 octets. Chacun est un 4 octets entier signé, écrit en binaire. Je suis assez nouveau à Python, et ne semble pas possible de l'obtenir pour fonctionner. Toutes les suggestions? Soemthing comme cette? J'ai besoin d'un contrôle complet sur combien d'octets chaque entier (et plus tard, virgule flottante de 4 octets ).
Grâce
OriginalL'auteur Schafer | 2014-08-06
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin de la struct module.
Le premier argument dans la struct.pack est la chaîne de format.
Le premier caractère dans la chaîne de format dicte l'ordre des octets ou endianness des données (c'Est le plus ou le moins important octet stocké premier - big-endian ou little-endian). Endianness varie d'un système à l'autre. Si ">" ne fonctionne pas, essayez "<".
Le deuxième caractère de la chaîne de format est le type de données. Sans surprise, le "i" signifie " entier et le "f" signifie " flotter. Le nombre d'octets est déterminé par le type. Short ou un "h" par exemple sont deux octets de long. Il y a aussi des codes pour les types non signés. "H" correspond à un unsigned short par exemple.
Le deuxième argument struct.pack est bien sûr la valeur à être emballés dans les octets de l'objet.
Voici la partie où je vous dis que j'ai menti sur un certain nombre de choses. J'ai d'abord dit que le nombre d'octets est déterminé par le type. Ce n'est que partiellement vrai. La taille d'un type donné est techniquement dépendants de la plateforme comme le C/C++ standard (struct module est basé sur) indique uniquement minimum tailles. Cela m'amène à la deuxième mensonge. Le premier caractère dans la chaîne de format code aussi si la norme (minimum) nombre d'octets ou de l'indigène (dépendants de la plateforme) nombre d'octets sont utilisés. (Les deux ">" et "<" garantir que la norme, le nombre minimal d'octets est utilisé qui est, en fait, quatre dans le cas d'un nombre entier "je" ou float "f".) En outre, il encode le l'alignement des données.
La la documentation sur le module struct sur les tables de la chaîne de format des paramètres.
Vous pouvez aussi mettre plusieurs primitives, en un seul octets de l'objet et de réaliser le même résultat.
Et bien sûr, vous pouvez analyser des données binaires avec des struct.décompresser.
with
instruction pour éviter d'oublier declose
!Attention, le symbole "> " en frappé.pack format de la chaîne est uniquement pour big-endian système, comme Motorola 68000 ou PowerPC G5, il vaut mieux utiliser de symbole "@" qui permettra de créer le format natif ( big-endian ou little-endian), vous allez créer un fichier non transférable vers d'autres plataforms.
OriginalL'auteur M.J. Rayburn
En supposant que vous souhaitez en little-endian, vous pourriez faire quelque chose comme cela pour écrire 42 de un à quatre octets binaires.
A2 est de 42 en hexadécimal, et les octets
'\xA2\0\0\0'
fait le premier octet égal à 42, suivie de trois vide octets. Ce code écrit l'octet: 42, 0, 0, 0.Votre code écrit les octets pour représenter le caractère '4' en UTF 32 et les octets pour représenter 2 en UTF 32. Cela signifie qu'il écrit les octets: 52, 0, 0, 0, 50, 0, 0, 0, parce que chaque caractère est de quatre octets lorsqu'ils sont encodés en UTF 32.
Également d'avoir un éditeur hexadécimal pour le débogage peut être utile pour vous, alors vous pouvez voir les octets que votre programme est sortie et pas seulement la taille.
chr(y&0xFF) + chr((y>>8)&0xFF) + chr((y>>(8*2))&0xFF) + chr((y>>(8*3))&0xFF)
devrait travailler pour la conversion de quatre octets entiers où y est le nombre à convertir en chaîne de caractères. Il fonctionne en déplaçant vers le bas le nombre et en entrant les octets un par un. Je ne sais pas comment faire pour faire des nombres à virgule flottante. - Si vous savez quels octets que vous voulez et utilisez python3, vous pouvez utiliserbytes([<1st byte>, <2nd byte>, <3rd byte>, <4th byte>])
. Remplacer les <>'s avec les octets que vous voulez.OriginalL'auteur Algorithmic Canary
Dans mon problème Écrire une chaîne binaire en fichier binaire Python 3.4 je fais comme ceci:
OriginalL'auteur Green Carpet