2010-07-25 27 views
14

Digamos que file.txt.gz tiene 2GB, y quiero ver las últimas 100 líneas más o menos. zcat <file.txt.gz | tail -n 100 pasaría por todo esto.Leyendo las últimas líneas del archivo de texto comprimido

Entiendo que los archivos comprimidos no se pueden acceder aleatoriamente, y si corté, digamos los últimos 5MB, los datos inmediatamente después del corte serán basura, pero ¿puede gzip resincronizar y decodificar el resto de la transmisión?

Si lo entiendo correctamente gzip stream es un flujo directo de comandos que describen qué salida, debería ser posible sincronizar con eso. Luego está la ventana deslizante de 32kB de los datos sin comprimir más recientes, que comienza como basura, por supuesto, si comenzamos en el medio, pero supongo que normalmente se llenaría de datos reales rápidamente, y desde ese punto la descompresión es trivial (bueno, es posible que algo se vuelva a copiar una y otra vez desde el inicio del archivo hasta el final, para que la ventana deslizante no se borre nunca, me sorprendería si fuera tan común, y si eso sucede, solo procesamos todo el archivo).

No estoy terriblemente ansioso por hacer este kin de hackers gzip yo mismo. ¿Alguien lo ha hecho antes, para tratar con archivos corruptos si nada más?

Alternativamente, si gzip realmente no puede hacer eso, ¿hay quizás algún otro programa de compresión de flujo que funcione de forma parecida, excepto que permite la resincronización a mitad de camino?

EDIT: encontré pure Ruby reimplementation of zlib y lo pirateé para imprimir las edades de los bytes dentro de la ventana deslizante. Resulta que las cosas se copian una y otra vez mucho e incluso después de 5MB + la ventana deslizante todavía contiene elementos de los primeros 100 bytes y de lugares aleatorios en todo el archivo.

Ni siquiera podemos evitarlo leyendo los primeros bloques y los últimos bloques, ya que esos primeros bytes no se referencian directamente, es solo una cadena muy larga de copias, y la única forma de averiguar lo que se refiere a es por procesarlo todo.

Básicamente, con las opciones predeterminadas, lo que quería es probablemente imposible.

Por otro lado zlib tiene la opción Z_FULL_FLUSH que borra esta ventana deslizante para sincronizar. Entonces la pregunta sigue en pie. Suponiendo que zlib se sincronice de vez en cuando, ¿hay alguna herramienta para leer solo el final sin procesarlo todo?

+0

Echa un vistazo a la pregunta duplicada http://stackoverflow.com/questions/14225751/random-access-to-gzipped-files and zran http://www.zlib.net/zlib_faq.html#faq28 –

+1

Esa pregunta realmente tiene nada que ver con mi problema, 'Z_FULL_FLUSH' era la verdadera solución. – taw

+0

¡Genial! ¿Puedes publicar tu solución? –

Respuesta

1

Z_FULL_FLUSH emite una secuencia de bytes conocida (00 00 FF FF) que puede utilizar para sincronizar. This link puede ser útil.

+6

el enlace está muerto ... – stepancheg

0

Esta es la diferencia entre las cifras de bloque y flujo. Debido a que gzip es un cifrado de flujo, es posible que necesite todo el archivo hasta cierto punto para descifrar los bytes en ese punto.

Como mencionas, cuando la ventana se borra, estás dorado. Pero no hay garantía de que zlib haga esto con la frecuencia suficiente ... Sugiero que busque hacia atrás desde el final del archivo y busque el marcador para una descarga completa.

Cuestiones relacionadas