Trabajando con archivos binarios
¿Qué es un bytearray?
Un bytearray es una clase en Python que permite almacenar datos en forma de una secuencia mutable de bytes. Es especialmente útil cuando se trabaja con datos binarios, como imágenes, archivos de audio o cualquier otro tipo de información que no esté en formato de texto. A diferencia de las cadenas de bytes (bytes), que son inmutables, los bytearray son mutables, lo que significa que puedes cambiar su contenido después de crearlos.
Sus características son:
- Mutable: Puedes modificar un
bytearraydespués de haberlo creado. Esto incluye cambiar, agregar o eliminar bytes. - Almacenamiento de datos amorfos: Un
bytearraypuede contener datos que no tienen una estructura predefinida, lo que es ideal para datos binarios. - Indexación: Puedes acceder a los elementos de un
bytearrayutilizando la indexación convencional, como lo harías con una lista. - Función
len(): Puedes utilizar la funciónlen()para obtener el número de bytes en unbytearray. - Valores enteros: Los elementos del
bytearraydeben ser enteros. Intentar establecer un elemento con un valor que no sea un entero provocará una excepciónTypeError. - Rango de valores: Cada elemento del
bytearraydebe ser un valor entero dentro del rango de 0 a 255. Si intentas asignar un valor fuera de este rango, se generará una excepciónValueError. - Impresión de elementos: Puedes imprimir los elementos de un
bytearrayutilizando la funciónhex(), lo que permite visualizar los valores en formato hexadecimal. - Inicialización: Puedes crear un
bytearrayde varias maneras. Por ejemplo:- Con un tamaño fijo:
data = bytearray(10)crea unbytearraycon capacidad para 10 bytes, inicializados a cero. - Con una cadena de bytes:
data = bytearray(b"hello")crea unbytearraya partir de una cadena de bytes. - Con una lista de enteros:
data = bytearray([65, 66, 67])crea unbytearrayque contiene los bytes correspondientes a los valores enteros (en este caso, A, B y C).
- Con un tamaño fijo:
Aquí hay un ejemplo que ilustra algunas operaciones comunes con un bytearray:
# Crear un bytearray de 10 bytes
data = bytearray(10)
print(data) # Salida: bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
# Modificar un byte
data[0] = 65 # Cambiar el primer byte a 65 (corresponde a 'A')
print(data) # Salida: bytearray(b'A\x00\x00\x00\x00\x00\x00\x00\x00\x00')
# Agregar nuevos bytes
data.append(66) # Agregar 66 (corresponde a 'B')
print(data) # Salida: bytearray(b'A\x00\x00\x00\x00\x00\x00\x00\x00\x00B')
# Convertir a bytes
bytes_data = bytes(data)
print(bytes_data) # Salida: b'A\x00\x00\x00\x00\x00\x00\x00\x00\x00B'
Veamos otro ejemplo:
data = bytearray(10)
for i in range(len(data)):
data[i] = 10 - i
for b in data:
print(hex(b))
Escritura en un archivo binario
Veamos cómo escribir un bytearray en un archivo binario y cómo leer ese contenido de nuevo en Python. Para escribir un bytearray en un archivo binario, debes seguir algunos pasos importantes:
- Se crea un
bytearraycon valores. Por ejemplo, puedes inicializarlo con valores a partir de 10, o puedes usar la funciónord('a')para obtener valores ASCII. - Abre el archivo en modo binario para escritura (
'wb'), lo que indica que estás trabajando con datos binarios. - Utiliza el método
write()para enviar elbytearrayal archivo. Este método devuelve la cantidad de bytes escritos correctamente. - Cerramos el archivo después de la escritura.
Aquí tienes el código que realiza la escritura de un bytearray en un archivo binario:
from os import strerror
# Inicializa el bytearray
data = bytearray(10)
# Llena el bytearray con valores
for i in range(len(data)):
data[i] = 10 + i # Valores de 10 a 19
try:
# Abre el archivo en modo binario para escritura
binary_file = open('file.bin', 'wb')
binary_file.write(data) # Escribe el bytearray en el archivo
binary_file.close() # Cierra el archivo
except IOError as e:
print("Se produjo un error de E/S:", strerror(e.errno))
Lectura de un archivo binario
Para leer el contenido de un archivo binario y almacenarlo en un bytearray, se utiliza el método readinto(), que llena un bytearray existente con los datos leídos. Aquí están los pasos:
- Abre el archivo en modo binario para lectura (
'rb'). - Usa el método
readinto()para leer los bytes directamente en unbytearrayya creado. Este método devuelve el número de bytes leídos con éxito. - Puedes imprimir el contenido del
bytearraypara verificar que los datos leídos son correctos.
Aquí tienes el código que lee el bytearray de un archivo binario:
from os import strerror
data = bytearray(10) # Crea un bytearray con espacio para 10 bytes
try:
# Abre el archivo en modo binario para lectura
binary_file = open('file.bin', 'rb')
num_bytes_read = binary_file.readinto(data) # Llena el bytearray con datos
binary_file.close() # Cierra el archivo
# Imprime los valores leídos en formato hexadecimal
for b in data:
print(hex(b), end=' ')
except IOError as e:
print("Se produjo un error de E/S:", strerror(e.errno))
Lectura de ficheros binarios con read()
Tenemos una forma alternativa para leer archivos binarios: El método read() ofrece una forma sencilla de leer el contenido completo de un archivo binario en Python. A diferencia de readinto(), que requiere un bytearray existente para llenar, read() crea un nuevo objeto de tipo bytes, que es inmutable.
A continuación, se presenta el código que escribe un bytearray en un archivo binario y luego lo lee usando read():
from os import strerror
# Inicializa el bytearray
data = bytearray(10)
# Llena el bytearray con valores
for i in range(len(data)):
data[i] = 10 + i # Valores de 10 a 19
try:
# Abre el archivo en modo binario para escritura
binary_file = open('file.bin', 'wb')
binary_file.write(data) # Escribe el bytearray en el archivo
binary_file.close() # Cierra el archivo
except IOError as e:
print("Se produjo un error de E/S:", strerror(e.errno))
# Ingresa aquí el código que lee los bytes del stream.
try:
# Abre el archivo en modo binario para lectura
binary_file = open('file.bin', 'rb')
# Lee todo el contenido del archivo en un objeto de bytes
data = binary_file.read()
binary_file.close() # Cierra el archivo
# Convierte el objeto de bytes a bytearray para manipulación
byte_data = bytearray(data)
# Imprime los valores leídos en formato hexadecimal
for b in byte_data:
print(hex(b), end=' ')
except IOError as e:
print("Se produjo un error de E/S:", strerror(e.errno))
El método read() también permite especificar el número máximo de bytes a leer al invocarlo con un argumento. Esto es útil cuando deseas controlar la cantidad de datos que se leen del archivo en una sola operación.
- Número de Bytes: Al pasar un argumento,
read(n)intentará leer hastanbytes del archivo. - Longitud del Objeto Devuelto: La longitud del objeto devuelto por
read(n)puede ser menor quensi se alcanza el final del archivo antes de haber leído todos los bytes solicitados.
A continuación, se muestra un ejemplo que escribe un bytearray en un archivo binario y luego lee los primeros 5 bytes usando el método read():
from os import strerror
# Inicializa el bytearray
data = bytearray(10)
# Llena el bytearray con valores
for i in range(len(data)):
data[i] = 10 + i # Valores de 10 a 19
try:
# Abre el archivo en modo binario para escritura
binary_file = open('file.bin', 'wb')
binary_file.write(data) # Escribe el bytearray en el archivo
binary_file.close() # Cierra el archivo
except IOError as e:
print("Se produjo un error de E/S:", strerror(e.errno))
# Ingresa aquí el código que lee los bytes del stream.
try:
# Abre el archivo en modo binario para lectura
binary_file = open('file.bin', 'rb')
# Lee los primeros 5 bytes del archivo
data = bytearray(binary_file.read(5)) # Leer 5 bytes
binary_file.close() # Cierra el archivo
# Imprime los valores leídos en formato hexadecimal
for b in data:
print(hex(b), end=' ')
except IOError as e:
print("Se produjo un error de E/S:", strerror(e.errno))