"mmap" --- Soporte de archivos mapeados en memoria
**************************************************

======================================================================

Los objetos de archivo mapeados en memoria se comportan como
"bytearray" y como *objetos de archivo*. Puede usar objetos mmap en la
mayoría de los lugares donde se espera "bytearray"; por ejemplo, puede
usar el módulo "re" para buscar en un archivo mapeado en memoria.
También puede cambiar un solo byte haciendo "obj[índice] = 97", o
cambiar una subsecuencia asignando a un segmento: "obj[i1: i2] =
b'...'". También puede leer y escribir datos comenzando en la posición
actual del archivo, y "seek()" a través del archivo a diferentes
posiciones.

Un archivo mapeado en memoria se crea con el constructor "mmap", que
es diferente en Unix y en Windows.  En cualquier caso, debes
proporcionar un descriptor de archivo para un archivo abierto para la
actualización. Si deseas mapear un objeto archivo de Python existente,
use su método "fileno()" para obtener el valor correcto para el
parámetro *fileno*.  De otra manera, puedes abrir el archivo usando la
función "os.open()", que retorna un descriptor de archivo directamente
(el archivo aún necesita ser cerrado cuando hayas terminado).

Nota:

  Si quieres crear un mapeado en memoria para un archivo con permisos
  de escritura y en el búfer, debes ejecutar la función "flush()". Es
  necesario para asegurar que las modificaciones locales a los búfer
  estén realmente disponible para el mapeado.

Para las versiones del constructor de tanto Unix como de Windows,
*access* puede ser especificado como un parámetro nombrado opcional.
*access* acepta uno de cuatro valores: "ACCESS_READ", "ACCESS_WRITE",
o "ACCESS_DEFAULT" para especificar una memoria de sólo lectura,
*write-through*, o *copy-on-write* respectivamente, o "ACCES_DEFAULT"
para deferir a *prot*. El parámetro *access* se puede usar tanto en
Unix como en Windows.  Si *access* no es especificado, el *mmap* de
Windows retorna un mapeado *write-through*.  Los valores de la memoria
inicial para los tres tipos de acceso son tomados del archivo
especificado.  La asignación a una mapa de memoria "ACCESS_READ" lanza
una excepción "TypeError".  La asignación a un mapa de memoria
"ACCESS_WRITE" afecta tanto a la memoria como al archivo subyacente.
La asignación a un mapa de memoria "ACCES_COPY" afecta a la memoria
pero no actualiza el archivo subyacente.

Distinto en la versión 3.7: Se añadió la constante "ACCESS_DEFAULT".

Para mapear memoria anónima, se debe pasar -1 como el *fileno* junto
con la longitud.

class mmap.mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT[, offset])

   **(En la versión de Windows)** Mapea *length* bytes desde el
   archivo especificado por el gestor de archivo *fileno*, y crea un
   objeto *mmap*. Si *length* es más largo que el tamaño actual del
   archivo, el archivo es extendido para contener *length* bytes. Si
   *length* es "0", la longitud máxima del map es la tamaño actual del
   archivo, salvo que si el archivo está vacío Windows lanza una
   excepción (no puedes crear un mapeado vacío en Windows)

   *tagname*, si está especifico y no es "None", es una cadena que
   proporciona el nombre de la etiqueta para el mapeado.  Windows te
   permite tener varios mapeados diferentes del mismo archivo.  Si
   especificas el nombre de una etiqueta existente, la etiqueta se
   abre, de otro modo una crea una nueva etiqueta.  Si este parámetro
   se omite o es "None", el mapeado es creado sin un nombre. Evitar el
   uso del parámetro etiqueta te ayudará a mantener tu código portable
   entre Unix y Windows.

   *offset* puede ser especificado como un *offset* entero no
   negativo. las referencias de *mmap* serán relativas al *offset*
   desde el comienzo del archivo. *offset* es por defecto 0. *offset*
   debe ser un múltiplo de "ALLOCATIONGRANULARITY".

   Lanza un evento de inspección "mmap.__new__" con los argumentos
   "fileno", "length", "access", "offset".

class mmap.mmap(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE|PROT_READ, access=ACCESS_DEFAULT[, offset])

   **(En la versión de Unix)** Mapea *length* bytes desde el archivo
   especificado por el descriptor de archivo *fileno*, y retorna un
   objeto *mmap*.  Si *length* es "0", la longitud máxima del map será
   el tamaño actual del archivo cuando "mmap" sea llamado.

   *flags* especifica la naturaleza del mapeado. "MAP_PRIVATE" crea un
   mapeado *copy-on-write* privado, por lo que los cambios al
   contenido del objeto *mmap* serán privados para este proceso, y
   "MAP_SHARED" crea un mapeado que es compartido con todos los demás
   procesos que mapean las mismas áreas del archivo.  El valor por
   defecto es "MAP_SHARED".

   *prot*, si se especifica, proporciona la protección de memoria
   deseado; los dos valores más útiles son "PROT_READ" y "PROT_WRITE",
   para especificar que las páginas puedan ser escritas o leídas.
   *prot* es por defecto "PROT_READ|PROT_WRITE".

   *access* puede ser especificado en lugar de *flags* y *prot* como
   un parámetro nombrado opcional.  Es un error especificar tanto
   *flags*, *prot* como *access*. Véase la descripción de *access*
   arriba por información de cómo usar este parámetro.

   *offset* puede ser especificado como un *offset* entero no
   negativo. Las referencias serán relativas al *offset* desde el
   comienzo del archivo. *offset* por defecto es 0. *offset* debe ser
   un múltiplo de "ALLOCATIONGRANULARITY" que es igual a "PAGESIZE" en
   los sistemas Unix.

   To ensure validity of the created memory mapping the file specified
   by the descriptor *fileno* is internally automatically synchronized
   with physical backing store on macOS and OpenVMS.

   Este ejemplo muestra un forma simple de usar "mmap":

      import mmap

      # write a simple example file
      with open("hello.txt", "wb") as f:
          f.write(b"Hello Python!\n")

      with open("hello.txt", "r+b") as f:
          # memory-map the file, size 0 means whole file
          mm = mmap.mmap(f.fileno(), 0)
          # read content via standard file methods
          print(mm.readline())  # prints b"Hello Python!\n"
          # read content via slice notation
          print(mm[:5])  # prints b"Hello"
          # update content using slice notation;
          # note that new content must have same size
          mm[6:] = b" world!\n"
          # ... and read again using standard file methods
          mm.seek(0)
          print(mm.readline())  # prints b"Hello  world!\n"
          # close the map
          mm.close()

   "mmap" también puede ser usado como un gestor de contexto en una
   sentencia "with"

      import mmap

      with mmap.mmap(-1, 13) as mm:
          mm.write(b"Hello world!")

   Nuevo en la versión 3.2: Soporte del Gestor de Contexto.

   El siguiente ejemplo demuestra como crear un mapa anónimo y cambiar
   los datos entre los procesos padre e hijo:

      import mmap
      import os

      mm = mmap.mmap(-1, 13)
      mm.write(b"Hello world!")

      pid = os.fork()

      if pid == 0:  # In a child process
          mm.seek(0)
          print(mm.readline())

          mm.close()

   Lanza un evento de inspección "mmap.__new__" con los argumentos
   "fileno", "length", "access", "offset".

   Los objetos de archivos mapeados en memoria soportan los siguiente
   métodos:

   close()

      Cierra el *mmap*. Las llamadas posteriores a otros métodos del
      objeto resultarán en que se lance una excepción *ValueError*.
      Esto no cerrará el archivo abierto.

   closed

      "True" si el archivo está cerrado.

      Nuevo en la versión 3.2.

   find(sub[, start[, end]])

      Retorna el índice mínimo en el objeto donde la subsecuencia
      *sub* es hallada, tal que *sub* este contenido en el rango
      [*start*, *end*]. Los argumentos opcionales *start* y *end* son
      interpretados como en una notación de rebanada. Retorna "-1" si
      falla.

      Distinto en la versión 3.5: Ahora el objeto *bytes-like object*
      con permisos de escritura se acepta.

   flush([offset[, size]])

      Transmite los cambios hechos a la copia en memoria de una
      archivo de vuelta al archivo. Sin el uso de esta llamada no hay
      garantía que los cambios sean escritos de vuelta antes de que
      los objetos sean destruidos.  Si *offset* y *size* son
      especificados, sólo los cambios al rango de bytes dado serán
      transmitidos al disco; de otra forma, la extensión completa al
      mapeado se transmite.  *offset* debe ser un múltiplo de la
      constante "PAGESIZE" o "ALLOCATIONGRANULARITY".

      Se retorna "None" para indicar éxito.  Una excepción es lanzada
      cuando la llamada falla.

      Distinto en la versión 3.8: Anteriormente, se retornaba un valor
      diferente de cero cuando era exitoso; se retornaba cero cuando
      pasaba un error en Windows.  Se retornaba un valor de cero
      cuando era exitoso; se lanzaba una excepción cuando pasaba un
      error en Unix.

   madvise(option[, start[, length]])

      Envía un aviso *option* al kernel sobre la región de la memoria
      que comienza con *start* y se extiende *length* bytes.  *option*
      debe ser una de las constantes MADV_* disponibles en el sistema.
      Si *start* y *end* se omiten, se abarca al mapeo entero.  En
      algunos sistemas (incluyendo Linux), *start* debe ser un
      múltiplo de "PAGESIZE".

      Disponibilidad: Sistemas con la llamada al sistema "madvise()".

      Nuevo en la versión 3.8.

   move(dest, src, count)

      Copia los *count* bytes empezando en el *offset* *src* al índice
      de destino *dest*.  Si el *mmap* fue creado con "ACCESS_READ",
      entonces las llamadas lanzaran una excepción "TypeError".

   read([n])

      Retorna una clase "bytes" que contiene hasta *n* bytes empezando
      desde la posición del archivo actual. Si se omite el argumento,
      es "None" o negativo, retorna todos los bytes desde la posición
      actual del archivo hasta el final del mapeado. Se actualiza la
      posición del archivo para apuntar después de los bytes que se
      retornaron.

      Distinto en la versión 3.3: El argumento puede ser omitido o ser
      "None".

   read_byte()

      Retorna un byte en la posición actual del archivo como un
      entero, y avanza la posición del archivo por 1.

   readline()

      Retorna una sola línea, comenzando en la posición actual del
      archivo y hasta la siguiente nueva línea. La posición del
      archivo se actualiza para apuntar después de los bytes que se
      retornaron.

   resize(newsize)

      Redimensiona el mapa y el archivo subyacente, si lo hubiera. Si
      el *mmap* fue creado con "ACCESS_READ" o "ACCESS_COPY",
      redimensionar el mapa lanzará una excepción "TypeError".

   rfind(sub[, start[, end]])

      Retorna el índice más alto en el objeto donde la subsecuencia
      *sub* se encuentre, tal que *sub* sea contenido en el rango
      [*start*, *end*]. Los argumentos opcionales *start* y *end* son
      interpretados como un notación de rebanada. Retorna "-1" si
      falla.

      Distinto en la versión 3.5: Ahora el objeto *bytes-like object*
      con permisos de escritura se acepta.

   seek(pos[, whence])

      Establece la posición actual del archivo.  El argumento *whence*
      es opcional y es por defecto "os.SEEK_SET" o "0"
      (posicionamiento del archivo absoluto); otros valores son
      "os.SEEK_CUR" o "1" (búsqueda relativa a la posición actual) y
      "os.SEEK_END" o "2" (búsqueda relativa al final del archivo).

   size()

      Retorna el tamaño del archivo, que puede ser más grande que el
      tamaño del área mapeado en memoria.

   tell()

      Retorna la posición actual del puntero del archivo.

   write(bytes)

      Escribe los bytes en *bytes* en memoria en la posición actual
      del puntero del archivo y retorna el números de bytes escritos
      (nunca menos que "len(bytes)", ya que si la escritura falla, una
      excepción "ValueError" será lanzada).  La posición del archivo
      es actualizada para apuntar después de los bytes escritos.  Si
      el *mmap* fue creado con "ACCESS_READ", entonces escribirlo
      lanzará una excepción "TypeError".

      Distinto en la versión 3.5: Ahora el objeto *bytes-like object*
      con permisos de escritura se acepta.

      Distinto en la versión 3.6: Ahora se retorna el número de bytes
      escritos.

   write_byte(byte)

      Escribe el entero *byte* en la memoria en la posición actual del
      puntero del archivo; se avanza la posición del archivo por "1".
      Si el *mmap* es creado con "ACCES_READ", entonces escribirlo
      hará que se lance la excepción "TypeError".


Constantes MADV_*
=================

mmap.MADV_NORMAL
mmap.MADV_RANDOM
mmap.MADV_SEQUENTIAL
mmap.MADV_WILLNEED
mmap.MADV_DONTNEED
mmap.MADV_REMOVE
mmap.MADV_DONTFORK
mmap.MADV_DOFORK
mmap.MADV_HWPOISON
mmap.MADV_MERGEABLE
mmap.MADV_UNMERGEABLE
mmap.MADV_SOFT_OFFLINE
mmap.MADV_HUGEPAGE
mmap.MADV_NOHUGEPAGE
mmap.MADV_DONTDUMP
mmap.MADV_DODUMP
mmap.MADV_FREE
mmap.MADV_NOSYNC
mmap.MADV_AUTOSYNC
mmap.MADV_NOCORE
mmap.MADV_CORE
mmap.MADV_PROTECT

   Se pueden pasar estas opciones al método "mmap.madvise()".  No
   todas las opciones estarán presentes en todos los sistemas.

   Disponibilidad: Sistemas con la llamada al sistema *madvise()*.

   Nuevo en la versión 3.8.
