Comment lire des données binaires dans un tampon mutable en Python

Supposant que vous voulez lire des données binaires directement dans un tampon mutable sans aucune copie intermédiaire. Peut-être voulez-vous modifier des données sur place et les retranscrire dans un fichier.

Pour lire les données dans un tableau mutable, utilisez la méthode readinto() des fichiers. Par exemple:

import os.path

def read_into_buffer(fichier):
    tampon = bytearray(os.path.getsize(fichier))
    with open(fichier, 'rb') as f:
         f.readinto(tampon)
    return tampon

 

Voici un exemple qui illustre l’utilisation du code ci-dessus:

>>> # Ecrire un fichier d'exemple
>>> with open('exemple.bin', 'wb') as f:
...      f.write(b'Hello World')
...
>>> tampon = read_into_tamponfer('exemple.bin')
>>> tampon
bytearray(b'Hello World')
>>> tampon[0:5] = b'Hallo'
>>> tampon
bytearray(b'Hallo World')
>>> with open('nouveau_exemple.bin', 'wb') as f:
...     f.write(tampon)
...
11
>>>

 

La méthode readinto() des objets fichier Python peut être utilisée pour remplir n’importe quel tableau pré-alloué avec des données. Cela inclut même les tableaux créés à partir du module array ou des bibliothèques telles que numpy.

Contrairement à la méthode read() normale, readinto() remplit le contenu d’un tampon existant plutôt que d’allouer de nouveaux objets et de les renvoyer.

Ainsi, vous pourriez être en mesure de l’utiliser pour éviter de faire des allocations de mémoire supplémentaires. Par exemple, si vous lisez un fichier binaire composé d’enregistrements de même taille, vous pouvez écrire du code comme ceci:

taille_ligne = 32           # taille de chaque ligne

tampon = bytearray(taille_ligne)
with open('fichier', 'rb') as f:
    while True:
        n = f.readinto(tampon)
        if n < taille_ligne:
            break

        # utiliser le contenu du tampon
        ...

 

Une autre fonctionnalité intéressante à utiliser ici pourrait être un objet memoryview (vue mémoire), qui vous permet de faire des tranches zero-copy d’un tampon existant et même de changer son contenu. Par exemple:

>>> tampon
bytearray(b'Hello World')
>>> m1 = memoryview(tampon)
>>> m2 = m1[-5:]
>>> m2
<memory at 0x100681390>
>>> m2[:] = b'WORLD'
>>> tampon
bytearray(b'Hello WORLD')
>>>

 

Il faut faire attention en utilisant f.readinto(), vous devez toujours vérifier son code de retour, qui est le nombre d’octets réellement lus.

Si le nombre d’octets est inférieur à la taille de la mémoire tampon fournie, cela peut indiquer des données tronquées ou corrompues (par exemple, si vous attendiez un nombre exact d’octets à lire).

Enfin, soyez à l’affût d’autres fonctions liées à “into” dans différents modules de bibliothèques (par exemple, recv_into(), pack_into(), etc. De nombreuses autres parties de Python prennent en charge les E/S directes ou l’accès aux données qui peuvent être utilisées pour remplir ou modifier le contenu des tableaux et des tampons.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here