Saltar al contenido principal

7.2.7 Sistema de Archivos

Trabajar con persistencia no es solo leer y escribir contenido: también implica gestionar rutas, carpetas y archivos de forma segura y portable.

En este punto aprenderás a navegar por el sistema de archivos, construir rutas robustas, buscar ficheros por patrón y automatizar tareas comunes sin depender del sistema operativo.


1️⃣ Rutas y portabilidad: el problema real​

Un programa puede funcionar en tu equipo y fallar en otro solo por cómo construyes rutas.

Errores típicos:

  • Concatenar rutas con +.
  • Usar separadores manuales (\ o /).
  • Escribir rutas absolutas fijas (C:/...).

🟩 Qué debe cumplir una ruta robusta​

  • Funcionar en Windows, Linux y macOS.
  • No depender del usuario actual.
  • Ser legible y fácil de mantener.

🟦 Recomendación general​

  • Preferir pathlib para nuevas implementaciones.
  • Usar rutas relativas al proyecto o al script.

2️⃣ os vs pathlib​

Python ofrece dos enfoques principales.

🟩 Enfoque clásico con os​

Uso clásico
import os

ruta = os.path.join("data", "logs", "app.log")
print(os.path.exists(ruta))

🟦 Enfoque moderno con pathlib​

Uso moderno
from pathlib import Path

ruta = Path("data") / "logs" / "app.log"
print(ruta.exists())

🟨 Comparativa (os vs pathlib)​

Criterioos / os.pathpathlib
EstiloProcedimentalOrientado a objetos
LegibilidadMediaAlta
Composición de rutasos.path.join(...)Operador /
Recomendación actualCompatiblePreferido

3️⃣ Construcción y resolución de rutas​

pathlib permite expresar rutas de forma clara y segura.

🟩 Operaciones básicas​

Partes de una ruta
from pathlib import Path

ruta = Path("documentos") / "notas" / "enero.txt"

print(ruta.name) # enero.txt
print(ruta.stem) # enero
print(ruta.suffix) # .txt
print(ruta.parent) # documentos/notas

🟦 Rutas absolutas y normalización​

from pathlib import Path

ruta_relativa = Path("data/config.json")
ruta_absoluta = ruta_relativa.resolve()

print(ruta_absoluta)

🟨 Ruta relativa al script​

Base del módulo
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent
RUTA_DATOS = BASE_DIR / "data" / "db.json"

Este patrón evita errores cuando ejecutas el script desde carpetas distintas.


4️⃣ Operaciones comunes con archivos y carpetas​

🟩 Comprobación y creación​

from pathlib import Path

carpeta = Path("salidas")
carpeta.mkdir(parents=True, exist_ok=True)

archivo = carpeta / "resultado.txt"
if not archivo.exists():
archivo.touch()

🟦 Lectura y escritura directa con Path​

from pathlib import Path

ruta = Path("salidas") / "mensaje.txt"
ruta.write_text("Sistema operativo\n", encoding="utf-8")
contenido = ruta.read_text(encoding="utf-8")
print(contenido)

🟨 Renombrar, mover y borrar​

from pathlib import Path

origen = Path("salidas") / "mensaje.txt"
destino = Path("salidas") / "mensaje_final.txt"

origen.rename(destino)
# destino.unlink() # borra archivo
# Path("salidas").rmdir() # borra carpeta vacía
Cuidado al borrar

unlink() y rmdir() son acciones destructivas. Valida ruta y contexto antes de ejecutarlas.


5️⃣ Exploración de directorios y búsquedas (glob / rglob)​

Buscar ficheros por patrón es una tarea muy habitual (logs, backups, imágenes, etc.).

🟩 Listar contenido inmediato​

from pathlib import Path

for elemento in Path(".").iterdir():
print(elemento)

🟦 Filtrar por patrón con glob​

from pathlib import Path

for archivo in Path("logs").glob("*.log"):
print(archivo.name)

🟨 Búsqueda recursiva con rglob​

from pathlib import Path

for backup in Path(".").rglob("*.bak"):
print(backup)

glob() busca en la carpeta actual. rglob() también entra en subcarpetas.


6️⃣ Rutas relativas vs absolutas (decisión práctica)​

🟩 Cuándo usar rutas relativas​

  • Archivos del propio proyecto.
  • Recursos que viajarán con el repositorio.

🟦 Cuándo usar rutas absolutas​

  • Scripts de administración de sistema.
  • Integraciones donde la ubicación está definida externamente.

🟨 Recomendación operativa​

En aplicaciones académicas/proyecto: usa rutas relativas al BASE_DIR del script. Así evitas dependencias del directorio desde el que se lanza el comando.


7️⃣ Ejemplo completo: inspección y limpieza de backups​

Aquí se aplica un flujo típico de automatización: localizar archivos por patrón y generar un informe trazable.

Pipeline de sistema de archivos
from pathlib import Path

base = Path(".")
backup_dir = base / "backups"
backup_dir.mkdir(exist_ok=True)

# 1) localizar backups
backups = list(base.rglob("*.bak"))

# 2) generar informe
informe = base / "informe_backups.txt"
lineas = [f"Total backups encontrados: {len(backups)}\n"]
lineas += [f"- {b}\n" for b in backups]
informe.write_text("".join(lineas), encoding="utf-8")

Flujo recomendado: localizar -> clasificar -> actuar -> registrar resultado.


✅ Buenas prácticas recomendadas​

  • Usa pathlib como API principal.
  • Evita rutas absolutas hardcodeadas en código de proyecto.
  • Usa mkdir(..., exist_ok=True) para evitar fallos por carpeta existente.
  • Usa encoding="utf-8" al leer/escribir texto.
  • Antes de borrar, valida ruta y tipo de recurso.
  • Genera informes o logs de tareas automáticas de sistema de archivos.

🧪 Ejercicios prácticos – Operación Cartógrafo​

El equipo de mantenimiento necesita ordenar el sistema de archivos del proyecto: localizar backups, normalizar carpetas y generar informes automáticos.

Dispones de estos recursos: 👉 Descárgalos aquí

  • proyecto_sentinel/ -> estructura base con archivos mezclados
  • proyecto_sentinel/logs/ -> logs del sistema
  • proyecto_sentinel/backups/ -> copias antiguas

🟢 Fase 1 – Exploración del árbol​

🟩 Ejercicio 1 – Inventario inicial de rutas​

Recorre proyecto_sentinel y muestra:

  • Número total de archivos.
  • Número total de carpetas.
  • 3 rutas de ejemplo encontradas.

Objetivo: practicar recorrido y conteo.

🟦 Ejercicio 2 – Filtrado por extensión​

Encuentra todos los archivos .log y .bak. Muestra recuento por tipo.

Objetivo: dominar glob y rglob.

🟡 Fase 2 – Normalización de estructura​

🟨 Ejercicio 3 – Crear carpeta de salida​

Crea proyecto_sentinel/salidas si no existe.

Dentro, crea:

  • informe_logs.txt
  • informe_backups.txt

Objetivo: consolidar creación segura de rutas y archivos.

🟧 Ejercicio 4 – Informe de logs​

Genera informe_logs.txt con:

  • Total de .log encontrados.
  • Rutas relativas de cada log.

Objetivo: automatizar inspección de contenido del árbol.

🔵 Fase 3 – Operaciones sobre archivos​

🟥 Ejercicio 5 – Renombrado controlado​

Renombra error_old.log a error_legacy.log dentro de logs.

Si no existe, informa por pantalla sin romper el programa.

Objetivo: manejo seguro de operaciones de cambio de nombre.

🟫 Ejercicio 6 – Limpieza de backups temporales​

Detecta archivos *.tmp.bak y elimínalos.

Al final, muestra cuántos eliminaste.

Objetivo: aplicar limpieza con validación previa.

🔴 Fase Final – Entrega técnica​

🟪 Ejercicio 7 – Informe consolidado (resumen_fs.txt)​

Genera un informe final en salidas/resumen_fs.txt con:

  • Total de carpetas.
  • Total de archivos.
  • Total de .log.
  • Total de .bak.
  • Total de temporales eliminados.

Formato sugerido:

Carpetas: X
Archivos: X
Logs: X
Backups: X
Temporales eliminados: X