Pregunta

Tengo una aplicación que genera algunos archivos de registro grandes> 500 MB.

He escrito algunas utilidades en Python que me permite explorar rápidamente el archivo de registro y encontrar datos de interés. Pero ahora tengo algunos conjuntos de datos donde el archivo es demasiado grande para cargarlo todo en la memoria.

Yo quiero tanto a escanear el documento una vez, construir un índice y sólo cargar la sección del documento en la memoria que yo quiero mirar a la vez.

Esto funciona para mí cuando abro un 'archivo' leer una línea a la vez y almacenar el desplazamiento de la file.tell (). A continuación, puedo volver a esa sección del archivo después con file.seek (offset, 0).

Mi problema sin embargo es que es posible que tenga UTF-8 en los archivos de registro, así que necesito para abrirlos con el módulo de códecs (codecs.open(<filename>, 'r', 'utf-8')). Con el objeto resultante puedo llamar a buscar y contar, pero que no coinciden.

Asumo que los codecs tiene que hacer algo de búfer o tal vez devuelve el carácter que cuenta en lugar de bytes de decir?

¿Hay una manera de evitar esto?

¿Fue útil?

Solución

Si es verdad, esto suena como un error o limitación del módulo de codecs, ya que es de bytes y de caracteres compensaciones probablemente confusos.

Me gustaría utilizar la función open() regular para abrir el archivo, a continuación, seek() / tell() le dará Byte compensaciones que son siempre coherentes. Cada vez que desee leer, usar f.readline().decode('utf-8').

Ten cuidado, que el uso de la función f.read() que puede aterrizar en medio de un carácter multi-byte, lo que produce un error de decodificación UTF-8. readline() siempre funciona.

Esto no maneja de forma transparente la marca de orden de bytes para usted, pero es probable que los archivos de registro no tienen listas de materiales de todos modos.

Otros consejos

Para UTF-8, no es realmente necesario abrir el archivo con codecs.open. En cambio, es fiable para leer el archivo como una cadena de bytes en primer lugar, y sólo entonces decodificar una sección individual (invocando el método .decode en la cadena). Rompiendo el archivo en los límites de la línea es segura; la única manera insegura para dividir lo que sería en el medio de un carácter multi-byte (que se puede reconocer a partir de su valor de byte> 128).

Mucho de lo que sucede con UTF8 en Python tiene sentido si nos fijamos en cómo se ha hecho en Python 3. En su caso, que va a hacer un poco más sentido si se lee el capítulo Archivos de Inmersión en Python 3 : http://diveintopython3.org/files.html

El corto de él, sin embargo, es que file.seek y file.tell trabajo con posiciones de bytes, mientras que los caracteres Unicode puede tomar hasta varios bytes. Por lo tanto, si lo hace:

f.seek(10)
f.read(1)
f.tell()

Usted puede obtener fácilmente algo que no sea 17, dependiendo de lo que la longitud del carácter que uno lee lo era.

Actualización: No se puede hacer búsqueda / decir sobre el objeto devuelto por codec.open (). Es necesario utilizar un archivo normal, y decodificar las cuerdas a unicode después de leer.

No sé por qué no funciona, pero no puedo hacer que funcione. El buscan parece que sólo funciona una vez, por ejemplo. Luego hay que cerrar y volver a abrir el archivo, que es, por supuesto, no es útil.

The Tell no utiliza las posiciones de caracteres, pero no le muestra en su posición en el flujo es (pero probablemente donde el objeto de archivos subyacente es en la lectura del disco).

Así que probablemente debido a algún tipo de búfer subyacente, no puede hacerlo. Pero deocding después de la lectura funciona bien, así que a por ello.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top