Introducción a la Entrada/Salida en Python
En los sistemas operativos modernos, las aplicaciones no interactúan directamente con el disco. En cambio, solicitan al sistema operativo que abra un descriptor de archivo, que luego se utiliza para leer o escribir datos a través de interfaces proporcionadas por el sistema.
Lectura de Archivos
Para abrir un archivo en modo lectura, se emplea la función integrada open(), especificando la ruta y el modo de apertura. Por ejemplo:
manejador = open('/home/usuario/datos.txt', 'r')
Si el archivo no existe, se genera una excepción FileNotFoundError. Tras una apertura exitosa, el método read() permite obtener el contenido completo como una cadena de texto. Es crucial cerrar el archivo con close() para liberar recursos del sistema operativo.
Para garantizar el cierre correcto incluso ante errores, se puede usar un bloque try-finally:
try:
manejador = open('/ruta/al/archivo', 'r')
finally:
if manejador:
manejador.close()
Una alternativa más concisa es el manejo contextual con with, que cierra el archivo automáticamente:
with open('/ruta/al/archivo', 'r') as manejador:
contenido = manejador.read()
print(contenido)
Para archivos grandes, es preferible leer por fragmentos usando read(tamaño) o línea por línea con readline(). El método readlines() devuelve una lista de líneas, útil para archivos de configuración:
for linea in manejador.readlines():
print(linea.strip())
Objetos de Tipo Archivo
Los objetos con un método read(), como los devueltos por open(), se denominan "file-like objects" en Python. Ejemplos incluyen flujos de bytes en memoria, como los proporcionados por StringIO.
Archivos Binarios
Para leer archivos binarios como imágenes o videos, se utiliza el modo 'rb':
archivo_bin = open('/home/usuario/imagen.png', 'rb')
datos_binarios = archivo_bin.read()
archivo_bin.close()
Codificación de Caracteres
Al trabajar con archivos de texto no codificados en UTF-8, se debe especificar la codificación. Para manejar errores de decodificación, se puede usar el parámetro errors='ignore':
with open('/home/usuario/archivo_latin.txt', 'r', encoding='latin-1', errors='ignore') as f:
texto = f.read()
Escritura de Archivos
La escritura se realiza con el modo 'w' para texto o 'wb' para binario. Los datos pueden no escribirse inmediatamente en el disco, por lo que es esencial cerrar el archivo o usar el manejo contextual:
with open('/home/usuario/salida.txt', 'w') as f:
f.write('Datos de ejemplo')
StringIO y BytesIO
Para operaciones de E/S en memoria, StringIO maneja cadenas de texto, mientras que BytesIO trabaja con bytes. Ambos simulan la interfaz de archivos:
from io import StringIO
flujo_str = StringIO()
flujo_str.write('Texto temporal')
valor_str = flujo_str.getvalue()
from io import BytesIO
flujo_bytes = BytesIO()
flujo_bytes.write('Datos binarios'.encode('utf-8'))
valor_bytes = flujo_bytes.getvalue()
Manipulación de Archivos y Directorios
El módulo os en Python ofrece funciones para interactuar con el sistema de archivos. Por ejemplo, para obtener la ruta absoluta:
import os
ruta_actual = os.path.abspath('.')
La función os.path.join() construye rutas de manera portable entre sistemas operativos. Para listar archivos con filtros, se pueden usar listas por comprensión:
archivos_py = [nombre for nombre in os.listdir('.') if os.path.isfile(nombre) and nombre.endswith('.py')]
Serialización con pickle
El módulo pickle permite serializar objetos de Python para persistencia o transmisión. La serialización convierte un objeto en una secuencia de bytes:
import pickle
datos = {'clave': 'valor', 'numero': 42}
datos_serializados = pickle.dumps(datos)
with open('/home/usuario/datos.pkl', 'wb') as archivo:
pickle.dump(datos, archivo)
Para deserializar, se usan loads() o load(). Sin embargo, pickle es específico de Python y no recomendado para datos interoperables.
Serialización con JSON
JSON es un formato estándar para intercambio de datos. El módulo json en Python facilita la conversión entre objetos Python y JSON:
import json
diccionario = {'nombre': 'Ana', 'edad': 30}
cadena_json = json.dumps(diccionario)
with open('/home/usuario/datos.json', 'w') as archivo:
json.dump(diccionario, archivo)
Para personalizar la serialización de clases, se pueden usar los parámetros default y object_hook:
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
persona = Persona('Luis', 25)
cadena_json = json.dumps(persona, default=lambda obj: obj.__dict__)