una texto por linea leer formas especifica contenido archivo python file text mmap

por - leer una linea de texto en python



¿Cómo leer líneas de un archivo mmapped? (4)

La forma más concisa de iterar sobre las líneas de un mmap es

with open(STAT_FILE, "r+b") as f: map_file = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) for line in iter(map_file.readline, ""): # whatever

Parece que la interfaz mmap solo soporta readline (). Si trato de iterar sobre el objeto obtengo carácter en lugar de líneas completas.

¿Cuál sería el método "pythonic" de leer un archivo mmap''ed línea por línea?

import sys import mmap import os if (len(sys.argv) > 1): STAT_FILE=sys.argv[1] print STAT_FILE else: print "Need to know <statistics file name path>" sys.exit(1) with open(STAT_FILE, "r") as f: map = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) for line in map: print line # RETURNS single characters instead of whole line


Lo siguiente es razonablemente conciso:

with open(STAT_FILE, "r") as f: m = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) while True: line = m.readline() if line == "": break print line m.close()

Tenga en cuenta que la line conserva la nueva línea, por lo que le gustaría eliminarlo. También es la razón por la que if line == "" hace lo correcto (una línea vacía se devuelve como "/n" ).

La razón por la que la iteración original funciona de la manera en que lo hace es que mmap intenta parecerse tanto a un archivo como a una cadena. Se ve como una cadena para los propósitos de iteración.

No tengo idea de por qué no puede (o decide no) proporcionar readlines()/xreadlines() .


Modifiqué tu ejemplo así:

with open(STAT_FILE, "r+b") as f: m=mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) while True: line=m.readline() if line == '''': break print line.rstrip()

Sugerencias:

  • No llame a un map variable, esta es una función incorporada.
  • Abra el archivo en modo r+b , como en el ejemplo de Python en la página de ayuda de mmap . Indica: En cualquier caso, debe proporcionar un descriptor de archivo para un archivo abierto para actualización . Consulte http://docs.python.org/library/mmap.html#mmap.mmap .
  • Es mejor no usar los nombres de las variables globales UPPER_CASE_WITH_UNDERSCORES , como se menciona en los Nombres de variables globales en https://www.python.org/dev/peps/pep-0008/#global-variable-names . En otros lenguajes de programación (como C), las constantes a menudo se escriben en mayúsculas.

Espero que esto ayude.

Edit: Hice algunas pruebas de sincronización en Linux porque el comentario me dio curiosidad. Aquí hay una comparación de los tiempos realizados en 5 ejecuciones secuenciales en un archivo de texto de 137MB.

Acceso normal a archivos:

real 2.410 2.414 2.428 2.478 2.490 sys 0.052 0.052 0.064 0.080 0.152 user 2.232 2.276 2.292 2.304 2.320

Acceso a archivos mmap :

real 1.885 1.899 1.925 1.940 1.954 sys 0.088 0.108 0.108 0.116 0.120 user 1.696 1.732 1.736 1.744 1.752

Esos tiempos no incluyen la declaración de print (lo excluí). Siguiendo estos números, diría que el acceso a los archivos asignados a la memoria es bastante más rápido.

Edición 2: utilizando python -m cProfile test.py los siguientes resultados:

5432833 2.273 0.000 2.273 0.000 {method ''readline'' of ''file'' objects} 5432833 1.451 0.000 1.451 0.000 {method ''readline'' of ''mmap.mmap'' objects}

Si no me equivoco, entonces mmap es un poco más rápido.

Además, parece que not len(line) tiene un rendimiento peor que la line == '''' , al menos así es como interpreto la salida del generador de perfiles.


Python 2.7 de 32 bits en Windows es más del doble de rápido que en un archivo con formato mm:

En un archivo de texto de línea de 27 MB y 509 k (mi función "analizar" no es interesante, en su mayoría solo lee la línea () es muy rápido):

with open(someFile,"r") as f: if usemmap: m=mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) else: m=f e.parse(m)

Con MMAP:

read in 0.308000087738

Sin MMAP:

read in 0.680999994278