Los archivos grandes pueden procesarse sin cargar todo su contenido manualmente en un único objeto de bytes. mmap en Python crea un mapeo entre una región del archivo y el espacio de memoria virtual del proceso. El objeto resultante se comporta al mismo tiempo como archivo y como array mutable de bytes.
La técnica sirve para búsquedas de patrones, índices binarios, almacenamiento embebido, comunicación entre procesos y actualización de regiones fijas. No hace que cualquier operación sea automáticamente más rápida y exige atención a permisos, alineación, concurrencia, tamaño y persistencia. Esta guía cubre lectura, escritura, copy-on-write, memoria anónima, diferencias entre plataformas, flushing y cierre de recursos.
El contenido complementa nuestras guías sobre fileinput, linecache, tempfile, filecmp y weakref.
Cómo funciona el mapeo
El sistema operativo asocia páginas del archivo con direcciones virtuales. Las páginas se cargan bajo demanda y el kernel gestiona caché y expulsión. Python puede usar índices, slices, búsquedas y métodos similares a archivos.
El coste del almacenamiento sigue existiendo. Los page faults, el acceso aleatorio y la presión de memoria pueden dominar el rendimiento.
Mapear un archivo completo para lectura
import mmap
with open("datos.bin", "rb") as archivo:
with mmap.mmap(
archivo.fileno(),
length=0,
access=mmap.ACCESS_READ,
) as memoria:
print(memoria[:16])length=0 solicita el tamaño actual en plataformas compatibles. Windows no permite este mapeo para un archivo vacío.
Acceso de solo lectura
ACCESS_READ impide cambios. Una asignación genera TypeError.
memoria[0] = 65 # TypeErrorPrefiere este modo para búsquedas y análisis. Reduce el riesgo de corrupción accidental.
Escritura persistente
with open("datos.bin", "r+b") as archivo:
with mmap.mmap(
archivo.fileno(),
0,
access=mmap.ACCESS_WRITE,
) as memoria:
memoria[0:4] = b"HEAD"
memoria.flush()Con ACCESS_WRITE, los cambios afectan al mapeo y al archivo. El slice de reemplazo debe conservar el mismo tamaño.
Copy-on-write
with open("datos.bin", "rb") as archivo:
with mmap.mmap(
archivo.fileno(),
0,
access=mmap.ACCESS_COPY,
) as memoria:
memoria[0:4] = b"TEST"Los cambios quedan privados y no actualizan el archivo. Es útil para experimentos, pero no equivale a crear una copia completa por anticipado.
Flush del archivo antes del mapa
Si un archivo escribible contiene cambios en buffers de Python, llama flush() antes de mapear.
archivo.write(b"contenido")
archivo.flush()
memoria = mmap.mmap(archivo.fileno(), 0)Así los datos locales estarán disponibles para el mapeo.
Buscar bytes
posicion = memoria.find(b"ERROR")
if posicion != -1:
print("encontrado en", posicion)find() y rfind() aceptan rangos. El módulo re también puede buscar directamente en mmap.
Expresiones regulares
import re
for match in re.finditer(rb"ID:\d+", memoria):
print(match.start(), match.group())Usa patrones de bytes. Interpretar texto exige conocer encoding y límites de caracteres multibyte.
Métodos de archivo
Los objetos tienen posición actual y métodos read(), readline(), seek(), tell() y write().
memoria.seek(0)
primera_linea = memoria.readline()
posicion = memoria.tell()Desde Python 3.13, seek() devuelve la nueva posición absoluta.
Índices y slices
primero = memoria[0]
cabecera = memoria[0:16]Asignar un índice requiere un entero de byte. Asignar un slice requiere bytes de longitud compatible.
Persistencia con flush
flush() solicita escribir las páginas modificadas.
memoria.flush()Se puede indicar offset y tamaño, pero el offset debe alinearse con PAGESIZE o ALLOCATIONGRANULARITY. Maneja excepciones.
Durabilidad no es transacción
Flush del mapa, sincronización del descriptor y consistencia ante crashes son temas relacionados pero distintos. Las aplicaciones transaccionales deben estudiar fsync, orden de escritura y reemplazo atómico.
Mmap no convierte el archivo en base de datos segura automáticamente.
Offsets alineados
El offset del constructor debe ser múltiplo de ALLOCATIONGRANULARITY. Para una región arbitraria, alinea el inicio hacia abajo y conserva un delta.
gran = mmap.ALLOCATIONGRANULARITY
base = inicio // gran * gran
delta = inicio - base
longitud = delta + tamanoAccede luego con memoria[delta:delta+tamano].
Tamaño de archivo y de mapa
La longitud del mapa define la región visible. size() puede devolver el tamaño del archivo, mientras len(memoria) devuelve la región mapeada.
No accedas fuera del límite. Cambios concurrentes del tamaño pueden tener consecuencias graves.
Redimensionar
resize() modifica mapa y archivo cuando corresponde. Los mapas read-only, copy-on-write o con trackfd=False no pueden redimensionarse.
En Windows, otros mapas del mismo archivo pueden bloquear la operación.
trackfd en Unix
Desde Python 3.13, Unix acepta trackfd=False. El descriptor no se duplica, pero size() y resize() dejan de funcionar.
Úsalo solo si el límite de descriptores es un problema real.
Memoria anónima
with mmap.mmap(-1, 4096) as memoria:
memoria.write(b"datos temporales")Pasar -1 crea una región no asociada a archivo regular. Puede actuar como buffer o memoria compartida.
Compartir entre procesos
En Unix, un mapa anónimo creado antes de fork() puede compartirse entre padre e hijo. Para código portable, multiprocessing.shared_memory puede ser más explícito.
La memoria compartida no incluye sincronización. Usa locks, semáforos o un protocolo atómico.
MAP_SHARED y MAP_PRIVATE
El constructor Unix permite MAP_SHARED para cambios visibles a otros procesos y MAP_PRIVATE para copy-on-write.
No especifiques access junto con flags y prot.
Diferencias en Windows
Windows acepta tagname para mapas con nombre, pero evitarlo mejora portabilidad. Los offsets deben respetar la granularidad.
Un mapa más largo que el archivo puede extenderlo en Windows. No dependas de esta diferencia sin pruebas.
madvise
En sistemas compatibles, madvise() comunica al kernel el patrón esperado.
if hasattr(memoria, "madvise"):
memoria.madvise(mmap.MADV_SEQUENTIAL)Las constantes varían por sistema. Mide el impacto.
Acceso secuencial y aleatorio
El mapeo no elimina la latencia. Los recorridos secuenciales aprovechan prefetch; el acceso aleatorio en archivos mayores que la RAM puede generar muchos page faults.
Haz benchmarks con datos representativos.
Escritores concurrentes
Dos procesos pueden modificar la misma región y romper invariantes. La coherencia de memoria no protege actualizaciones lógicas de varios pasos.
Define versiones, locks, checksums y protocolo de commit.
Truncado externo
Si otro proceso reduce el archivo mapeado, los accesos posteriores pueden fallar de forma grave o dependiente del sistema. Controla el ciclo de vida.
Cerrar recursos
Usa context managers. Cerrar mmap no cierra el objeto de archivo original.
with open("datos.bin", "rb") as archivo:
with mmap.mmap(archivo.fileno(), 0, access=mmap.ACCESS_READ) as memoria:
procesar(memoria)Las vistas de memoria activas pueden impedir el cierre.
Seguridad
Mapear un archivo no valida su contenido. Longitudes, offsets y registros internos pueden ser maliciosos. Comprueba límites antes de calcular slices con valores del archivo.
No mapees dispositivos o archivos especiales sin comprender sus efectos.
Pruebas
Prueba archivos vacíos, pequeños y grandes, mapas de lectura, copy-on-write, regiones alineadas, búsquedas ausentes, flush, concurrencia controlada, Windows y Unix.
Errores frecuentes
- Mapear un archivo vacío en Windows.
- Abrir con modo incompatible.
- Olvidar flush antes del mapeo.
- Usar offset no alineado.
- Suponer que
flush()ofrece transacción. - Asignar slices de tamaño diferente.
- Redimensionar con otros mapas activos.
- Compartir memoria sin sincronización.
Buenas prácticas
- Usa
ACCESS_READpor defecto. - Usa copy-on-write para cambios temporales.
- Valida tamaños y offsets.
- Cierra mapas con
with. - Mide patrones reales.
- Sincroniza escritores.
- Prueba diferencias de plataforma.
- No trates mmap como base transaccional.
Conclusión
mmap en Python ofrece acceso flexible y eficiente a archivos y regiones de memoria. Combina slices de bytes, métodos de archivo, búsqueda y compartición controlada.
El rendimiento depende del patrón y del sistema operativo. Usa permisos mínimos, alinea offsets, valida estructuras y coordina concurrencia. Consulta la documentación oficial de mmap y el manual mmap de Unix.





