7
votes

Comment lire / écrire des données binaires 16 bits dans Python 2.x?

Je dois lire et écrire des données binaires, où chaque élément de données:

  • Taille = 2 octets (16 bits)
  • Encodage = Complément de 2 signé 2
  • endiannes = grand ou petit (doit être Sélection sélectionnable)

    est-il possible sans utiliser de module externe? Si oui,

    1. Comment lire de telles données d'un binaire fichier en utilisant lecture () dans un tableau L de entiers?
    2. Comment écrire un tableau d'entiers l dans un fichier binaire utilisant écrire ()?

7 commentaires

Avez-vous regardé le module de structure de Python?


Je dirais que le module de struct serait le meilleur endroit pour commencer


L'utilisation de struct serait tout à fait inefficace, cependant, car vous devriez déballer les valeurs un par un.


@Sven Marnach: Avez-vous mesuré cela?


@ S.Lott: Oui, en répondant à Cette question l'an dernier. Je ne me souviens pas des chiffres exacts.


@Sven Marnach: "" "Déballez les valeurs un par un" ""? Considérons structure.unpack (byeorder / Str (len (Rawbytes) // 2) + "h", Rawbytes) byeorder est << / code> ou > comme vous le souhaitez. Remarque: Je ne prétends pas que cela soit plus rapide que la méthode , mais que je notez que la méthode TRAY nécessite parfois un supplémentaire de BYTESWAP étape.


@John: Vous avez parfaitement raison, je ne me souviens pas que vous pouvez utiliser un compte répété. Les mesures que j'ai faites pour la question liée ne s'appliquent pas à cette affaire.


5 Réponses :


11
votes

Je pense que vous êtes le mieux en utilisant le tableau module. Il stocke des données dans l'ordre des octets système par défaut, mais vous pouvez utiliser array.byteswap () pour convertir entre les commandes d'octets, et vous pouvez utiliser sys.byteorder pour interroger le système ordre d'octet. Exemple: xxx


2 commentaires

Plus généralement, voir que l'OP en vigueur veut un fichier_byteorder arg, utilisez si sys.byteorderner! = File_byteorder: B.Byteswap () En entrée et à la sortie.


@John: C'est pourquoi j'ai écrit "exemple" ci-dessus :)



2
votes
from array import array
# Edit:
from sys import byteorder as system_endian # thanks, Sven!
# Sigh...
from os import stat

def read_file(filename, endian):
    count = stat(filename).st_size / 2
    with file(filename, 'rb') as f:
        result = array('h')
        result.fromfile(f, count)
        if endian != system_endian: result.byteswap()
        return result

2 commentaires

array.fromfile () prend toujours deux paramètres.


Pouah. C'est totalement gênant. :(



1
votes

envisager d'utiliser

structure.unpack (byeorder + str (len (Rawbytes) // 2) + "H", Rawbytes)

byeorder est '<' ou '>' tel que désiré et de même pour l'emballage. Remarque: Je ne prétends pas que cela soit plus rapide que la méthode , mais que je notez que la méthode TRAY nécessite parfois un supplémentaire de BYTESWAP étape.


1 commentaires

Le struct way toujours a besoin d'un supplémentaire () étape. La principale différence est que vous vous retrouverez avec une liste Python, pendant que vous obtenez un tableau lorsque vous utilisez array.fromfile () .



1
votes

J'ai trouvé cela utile pour lire / écrire les données d'un fichier binaire dans une matrice numpue: xxx

espère que cela aide.


0 commentaires

1
votes

Comme demandé, sans aucun modules externes: xxx

dans la liste de compréhension, nous lisons tous les deux octets. Ensuite, avec une opération bitwise, nous concatéons ces 2 octets. Cela dépend de l'endianess pour savoir où écrire i + 1 et i


0 commentaires