Contactez-nous

Manipulation de fichiers binaires

Découvrez comment manipuler des fichiers binaires en Python. Apprenez les différences entre fichiers texte et binaires, comment lire et écrire des octets, et comment utiliser les modules struct et pickle pour la sérialisation.

Différences entre fichiers texte et binaires : comprendre l'encodage

Il est important de distinguer les fichiers texte des fichiers binaires. Les fichiers texte sont des fichiers qui contiennent du texte lisible par un humain, encodé selon un certain encodage de caractères (comme UTF-8, ASCII, Latin-1, etc.). Les fichiers binaires contiennent des données qui ne sont pas directement lisibles par un humain (images, vidéos, audio, exécutables, etc.).

La principale différence réside dans la façon dont les données sont représentées. Dans un fichier texte, chaque caractère est représenté par un ou plusieurs octets, selon l'encodage. Dans un fichier binaire, les octets représentent des données brutes, qui peuvent avoir n'importe quelle signification selon le format du fichier.

Lorsque vous ouvrez un fichier en Python, vous devez spécifier si vous voulez le traiter comme un fichier texte (mode `'t'`, par défaut) ou comme un fichier binaire (mode `'b'`).

Si vous ouvrez un fichier binaire en mode texte, Python essaiera de décoder les octets en utilisant l'encodage par défaut (généralement UTF-8), ce qui peut entraîner des erreurs ou des résultats inattendus. Si vous ouvrez un fichier texte en mode binaire, vous lirez les octets bruts de l'encodage, sans décodage.

Nous verrons des exemples de fichiers texte et binaires, et comment Python les traite différemment.

Lecture et écriture d'octets : manipulez les données brutes

Pour lire et écrire des données binaires, vous devez ouvrir le fichier en mode binaire (en ajoutant `'b'` au mode d'ouverture : `'rb'` pour lire, `'wb'` pour écrire, etc.).

Lorsque vous lisez un fichier binaire, les méthodes `read()`, `readline()` et `readlines()` renvoient des objets `bytes` (et non des chaînes de caractères). Un objet `bytes` représente une séquence d'octets. Vous pouvez accéder aux octets individuels d'un objet `bytes` en utilisant l'indexation (comme pour les listes), mais chaque élément est un entier entre 0 et 255 (la valeur de l'octet).

Lorsque vous écrivez dans un fichier binaire, vous devez passer un objet `bytes` à la méthode `write()`. Vous pouvez créer un objet `bytes` à partir d'une chaîne de caractères en utilisant la méthode `encode()` de la chaîne, en spécifiant l'encodage : `ma_chaine.encode('utf-8')`. Vous pouvez également créer un objet `bytes` directement en utilisant la syntaxe `b'...'` : `b'\x48\x65\x6c\x6c\x6f'` (ceci représente la chaîne "Hello" en ASCII).

Il est important de faire attention à l'endianness (boutisme) lorsque vous travaillez avec des données binaires. L'endianness détermine l'ordre dans lequel les octets d'un nombre multi-octets (comme un entier sur 4 octets) sont stockés en mémoire ou dans un fichier. Il existe deux principaux types d'endianness : big-endian (les octets de poids fort en premier) et little-endian (les octets de poids faible en premier).

Nous verrons des exemples de lecture et d'écriture d'octets, et comment gérer l'endianness.

Utilisation des modules `struct` et `pickle` pour la sérialisation : convertissez des objets Python en données binaires

Lorsque vous travaillez avec des fichiers binaires, vous avez souvent besoin de convertir des données structurées (comme des nombres, des chaînes de caractères, des listes, des dictionnaires) en une représentation binaire, et vice-versa. C'est ce qu'on appelle la sérialisation (conversion en binaire) et la désérialisation (conversion depuis le binaire).

Python propose deux modules principaux pour la sérialisation : `struct` et `pickle`.

Le module `struct` vous permet de convertir des données Python (principalement des nombres et des chaînes de caractères) en structures C (séquences d'octets), et vice-versa. Vous utilisez des chaînes de format pour spécifier le type et l'ordre des données. Par exemple, `'i'` représente un entier signé sur 4 octets, `'f'` représente un flottant sur 4 octets, `'s'` représente une chaîne de caractères. Vous pouvez également spécifier l'endianness.

Le module `pickle` vous permet de sérialiser et de désérialiser des objets Python arbitraires (y compris des objets de classes que vous avez définies). Il est plus puissant que `struct`, mais il est moins sûr (ne désérialisez jamais des données provenant d'une source non fiable avec `pickle`, car cela peut exécuter du code arbitraire).

Nous verrons comment utiliser `struct` et `pickle` pour sérialiser et désérialiser des données, et nous discuterons des avantages et des inconvénients de chaque module.